home *** CD-ROM | disk | FTP | other *** search
/ Aminet 33 / Aminet 33 - October 1999.iso / Aminet / docs / misc / amigapl.9903.lzh / amigapl.9903 / pci.lzx / Examples / pcinet / pcinetdevice.asm < prev    next >
Encoding:
Assembly Source File  |  1998-04-24  |  70.9 KB  |  2,480 lines

  1. ;---------------------------------------------------------------------------
  2. ;                    PCMCIA ethernet card driver for A1200
  3. ;---------------------------------------------------------------------------
  4. ;
  5. ; HISTORY:
  6. ;
  7. ; 10-4-97  v0.1 - Created by Bruce Abbott (bhabbott@inhb.co.nz)
  8. ;                      *** First Aminet Release ***
  9. ;
  10. ; 29-4-97  v0.2 - Implemented CMD_ONLINE/OFFLINE/FLUSH (for Miami).
  11. ;
  12. ;               - Enabled interrupts during RemoteWrite (no more serial
  13. ;                 port overruns!).
  14. ;
  15. ; 6-5-97   v0.3 - Added a flag so that we won't try to ReleaseCard()
  16. ;                 unless there was a successful OwnCard()!
  17. ;
  18. ; 17-5-97  v0.4 - CMD_CONFIGINTERFACE now overrides the default hardware
  19. ;                 address (for Maimi).
  20. ;
  21. ;               - Device now goes offline if the PCMCIA card is removed.
  22. ;
  23. ;               - CMD_ONEVENT implemented.
  24. ;
  25. ;               - Loosened hardware address verification to accept the
  26. ;                 Accton EN2216.
  27. ;
  28. ;               - Unrolled loops to improve data transfer speed. Now
  29. ;                 about 20% faster on an unexpanded A600.
  30. ;
  31. ;               - Hack to fix problem with missed interrupts. Now we
  32. ;                 clear the Gayle interrupt bits instead of letting
  33. ;                 card.resource do it for us.
  34. ;
  35. ;                        *** Second Aminet Release ***
  36. ;
  37. ; 29-7-97  v0.5 - Accepts 802.3 packets (untested).
  38. ;
  39. ;               - Sets BROADCAST bit in io_flags when appropriate.
  40. ;
  41. ;               - Now examines PCMCIA attribute memory to determine
  42. ;                 value to write into Card Configuration Register.
  43. ;
  44. ;               - If attribute memory not found, tries to open the file
  45. ;                 "s:cnetdev.config" to get Card Configuration Register
  46. ;                 offset, Configuration ID, and ROM Station Address.
  47. ;
  48. ;                        *** Third Aminet Release ***
  49. ;
  50. ;
  51. ; 13-03-1998  PCI version by Krzysztof Rudnik (rudnik@jantar.ias.wat.waw.pl)
  52.  
  53.         include amiga.i              ; commodore includes (WB1.3)
  54.         include sanaii.i             ; the essential network stuff
  55.         include cnet.i               ; hardware specific stuff
  56.  
  57.  
  58. Printer  EQU 0
  59. VERSION  EQU 2
  60. REVISION EQU 1
  61.  
  62.  
  63. ; 1uS delay before nic register access
  64. ; May not be required with slower CPU.
  65.  
  66. delay   MACRO
  67.         tst.b   $bfe001              ; at least 1uS, even on fast machines
  68.         ENDM
  69.  
  70. ;===========================================================================
  71.  
  72.         section device,CODE
  73.  
  74. start_exe:
  75.         move.l  4,execbase
  76.         move.l  #-1,D0          ; it's a device, not an application!
  77.         rts
  78.  
  79. romtag:
  80.         dc.w    RTC_MATCHWORD   ; RT_MATCHWORD
  81.         dc.l    romtag          ; RT_MATCHTAG
  82.         dc.l    Endcode         ; RT_ENDSKIP
  83.         dc.b    RTF_AUTOINIT    ; RT_FLAGS
  84.         dc.b    VERSION         ; RT_VERSION
  85.         dc.b    NT_DEVICE       ; RT_TYPE
  86.         dc.b    0               ; RT_PRI
  87.         dc.l    DeviceName      ; RT_NAME
  88.         dc.l    IDString        ; RT_IDSTRING
  89.         dc.l    Init            ; RT_INIT
  90.  
  91. Init:
  92.         dc.l    dd_extsize      ; data space size
  93.         dc.l    funcTable       ; pointer to function initializers
  94.         dc.l    dataTable       ; pointer to data initializers
  95.         dc.l    initRoutine     ; routine to run at startup
  96.  
  97. funcTable:
  98.         dc.l    Open_Device
  99.         dc.l    Close_Device
  100.         dc.l    _DevExpunge
  101.         dc.l    _Null
  102.         dc.l    _DevBeginIO
  103.         dc.l    _DevAbortIO
  104.         dc.l    -1
  105.  
  106. dataTable:
  107.         INITBYTE        LN_TYPE,NT_DEVICE
  108.         INITLONG        LN_NAME,DeviceName
  109.         INITBYTE        LIB_FLAGS,LIBF_SUMUSED!LIBF_CHANGED
  110.         INITWORD        LIB_VERSION,VERSION
  111.         INITWORD        LIB_REVISION,REVISION
  112.         INITLONG        LIB_IDSTRING,IDString
  113.         dc.w            0
  114.  
  115. AppMsg          STRINGR "This is not America !!!!"
  116.  
  117. InitMsg         STRINGR "Loading pcinet.device ..."
  118. NoResourceMsg   STRINGR "Unable to open micronik_pci.resource"
  119. NoLibraryMsg    STRINGR "Unable to open pciexpansion.library"
  120. NoMappingMsg    STRINGR "Unable to allocate mapping stru"
  121. InitMoreMsg     STRINGR "More then one network card detected"
  122. InitNoCardMsg   STRINGR "No network card detected"
  123. InitOKMsg       STRINGR "Device initialized successfully"
  124.  
  125. ;=======================================================
  126. ;                      initRoutine
  127. ;=======================================================
  128. ;
  129. ; Called after device has been allocated.
  130. ; This routine is single threaded
  131. ;
  132. ; input:   a0 = seglist
  133. ;          d0 = device
  134. ;          a6 = execbase
  135. ;
  136. initRoutine:
  137.         movem.l d1-d7/a0-a6,-(A7)
  138.         move.l  d0,a5
  139.         move.l  a0,dd_seglist(a5)  ; seglist for expunge
  140.         move.l  a6,execbase         ; local copy of execbase
  141.         ; in version 2.0 we can access PCI bus from interrupt routines
  142.         ; we don't need dedicated task 
  143.  
  144.         IFGT    Printer
  145.  
  146.         bsr     DPutMsg
  147.         dc.l    InitMsg
  148.  
  149.         ENDC
  150.  
  151.         ; open micronik_pci.resource
  152.         lea.l   pcirname(pc),a1
  153.         jsr     _LVOOpenResource(a6)
  154.         move.l  d0,dd_pcires(a5)
  155.         beq     InitFailNoResource
  156.  
  157.         ; zaalokowac pare PCIMapping
  158.         move.l  #0,dd_mapping_main(a5)
  159.         move.l  #0,dd_mapping_rx(a5)
  160.         move.l  #0,dd_mapping_tx(a5)
  161.         move.l  #0,dd_mapping_int(a5)
  162.         move.l  d0,a6
  163.         jsr     PCIRAllocPCIMapping(a6)
  164.         move.l  d0,dd_mapping_main(a5)
  165.         beq     InitFailNoMapping
  166.         jsr     PCIRAllocPCIMapping(a6)
  167.         move.l  d0,dd_mapping_rx(a5)
  168.         beq     InitFailNoMapping
  169.         jsr     PCIRAllocPCIMapping(a6)
  170.         move.l  d0,dd_mapping_tx(a5)
  171.         beq     InitFailNoMapping
  172.         jsr     PCIRAllocPCIMapping(a6)
  173.         move.l  d0,dd_mapping_int(a5)
  174.         beq     InitFailNoMapping
  175.         
  176.         ; open pciexpansion.library
  177.         move.l  execbase(pc),a6
  178.         lea.l   pciename(pc),a1
  179.         move.l  #0,d0
  180.         jsr     _LVOOpenLibrary(a6)
  181.         move.l  d0,dd_pcielib(a5)
  182.         tst.l   d0
  183.         beq     InitFailNoLibrary
  184.  
  185.         ; find NET card 
  186.         ; to to chyba lepiej zrobic w open unit - mozna wybrac karte
  187.         move.l  #0,a0
  188.         lea.l   NET_TAGS(pc),a1
  189.         move.l  d0,a6
  190.         jsr     PCIEFindPCIDev(a6)
  191.         move.l  d0,dd_pciconfig(a5)
  192.         beq     InitFailNoCard
  193.         move.l  d0,a0
  194.         lea.l   NET_TAGS(pc),a1
  195.         jsr     PCIEFindPCIDev(a6)
  196.         tst.l   d0
  197.         bne     InitFailMoreCards
  198.  
  199.         ; wpisac adresy bazowe do PCI mapping
  200.         move.l  dd_pciconfig(a5),a0
  201.         move.l  pcie_Cfg+pci_BaseAddress0(a0),d0
  202.         btst.l  #0,d0
  203.         beq     InitMemorySpace
  204. InitIOSpace:
  205.         and.l   #$FFFFFFFC,d0   ; wykasowac 2 najmlodsze bity
  206.         move.b  SPACE_IO,d1
  207.         bra     InitSpace
  208. InitMemorySpace:
  209.         and.l   #$FFFFFFF0,d0   ; wykasowac 4 najmlodsze bity
  210.         move.b  SPACE_MEMORY,d1
  211. InitSpace:
  212.  
  213.         move.l  dd_mapping_main(a5),a1
  214.         move.l  d0,pci_Address(a1)
  215.         move.b  d1,pci_space(a1)
  216.         move.b  pcie_Size0(a0),pci_sizebits(a1)
  217.         move.b  #0,pci_flags(a1)
  218.  
  219.         move.l  dd_mapping_rx(a5),a1
  220.         move.l  d0,pci_Address(a1)
  221.         move.b  d1,pci_space(a1)
  222.         move.b  pcie_Size0(a0),pci_sizebits(a1)
  223.         move.b  #0,pci_flags(a1)
  224.  
  225.         move.l  dd_mapping_tx(a5),a1
  226.         move.l  d0,pci_Address(a1)
  227.         move.b  d1,pci_space(a1)
  228.         move.b  pcie_Size0(a0),pci_sizebits(a1)
  229.         move.b  #0,pci_flags(a1)
  230.  
  231.         move.l  dd_mapping_int(a5),a1
  232.         move.l  d0,pci_Address(a1)
  233.         move.b  d1,pci_space(a1)
  234.         move.b  pcie_Size0(a0),pci_sizebits(a1)
  235.         move.b  #0,pci_flags(a1)
  236.  
  237.         IFGT    Printer
  238.  
  239.         bsr     DPutMsg
  240.         dc.l    InitOKMsg
  241.  
  242.         ENDC
  243.  
  244.         move.l  a5,d0
  245.         movem.l (A7)+,d1-d7/a0-a6
  246.         rts
  247.  
  248.  
  249. InitFailMoreCards:
  250.         bsr     DPutMsg
  251.         dc.l    InitMoreMsg
  252.         bra     InitFailCardNumber
  253.         
  254. InitFailNoCard:
  255.  
  256.         bsr     DPutMsg
  257.         dc.l    InitNoCardMsg
  258.  
  259. InitFailCardNumber:
  260.         move.l  dd_pcielib(a5),a1
  261.         move.l  execbase(pc),a6
  262.         jsr     _LVOCloseLibrary(a6)
  263.  
  264. InitFailNoLibrary:
  265.         bsr     DPutMsg
  266.         dc.l    NoLibraryMsg
  267.  
  268. InitFailNoMapping:
  269.         bsr     DPutMsg
  270.         dc.l    NoMappingMsg
  271.  
  272.         move.l  dd_pcires(a5),a6
  273.         move.l  dd_mapping_main(a5),a1
  274.         tst.l   a1
  275.         beq     .IF.map1
  276.         jsr     PCIRFreePCIMapping(a6)
  277. .IF.map1:
  278.         move.l  dd_mapping_rx(a5),a1
  279.         tst.l   a1
  280.         beq     .IF.map2
  281.         jsr     PCIRFreePCIMapping(a6)
  282. .IF.map2:
  283.         move.l  dd_mapping_tx(a5),a1
  284.         tst.l   a1
  285.         beq     .IF.map3
  286.         jsr     PCIRFreePCIMapping(a6)
  287. .IF.map3:
  288.         move.l  dd_mapping_int(a5),a1
  289.         tst.l   a1
  290.         beq     .IF.map4
  291.         jsr     PCIRFreePCIMapping(a6)
  292. .IF.map4:
  293.  
  294. InitFailNoResource:
  295.         bsr     DPutMsg
  296.         dc.l    NoResourceMsg
  297.  
  298.  
  299. InitExpunge:
  300.         move.l  #0,d0
  301.         movem.l (A7)+,d1-d7/a0-a6
  302.         rts
  303.  
  304.  
  305. _Null:
  306.         move.l  #0,d0
  307.         rts
  308.  
  309.  
  310.  
  311. OpenMsg         STRINGR "Open pcinet.device"
  312. DevOpenMsg      STRINGR "Device opened successfully"
  313. ;=================================================================
  314. ;                         Open Device
  315. ;=================================================================
  316. ;
  317. ; error = Open_Device(device, ioreq, unitnum, flags)
  318. ;  d0                   a6      a1     d0      d1
  319. ;
  320. Open_Device:
  321.         movem.l D2-D7/A2-A6,-(A7)
  322.         move.l  A6,A5                       ; a5 = device
  323.         move.l  A1,A4                       ; a4 = ioreq
  324.         move.l  D0,D4                       ; d4 = unit
  325.  
  326.         addq.w  #1,LIB_OPENCNT(a5)          ; expunge protection
  327.  
  328.         IFGT    Printer
  329.  
  330.         bsr     DPutMsg
  331.         dc.l    OpenMsg
  332.  
  333.         ENDC
  334.  
  335.         move.l  a5,a1
  336.         bsr     init_device     ; init device data structures
  337.                                 ; can be executed without PCI page
  338.  
  339.         move.l  a5,a0
  340.         move.l  a4,a1
  341.         move.l  d4,d0
  342.         bsr     Open_Unit                   ; open unit
  343.  
  344.         move.l  d0,IO_UNIT(a4)
  345.         beq.s   .OD.error
  346.  
  347.         move.l  A5,A1
  348.         bsr     init_card                   ; init PCMCIA card
  349.  
  350.         tst.l   D0
  351.         bne.s   .OD.error
  352.  
  353.  
  354.         move.l  a5,a1
  355.         bsr     init_nic                    ; init Network Interface Controller
  356.  
  357. **************************************************************
  358. * There is no sense to check now - we've checked during
  359. * device initialization
  360. * PCI cards are not removable - no insert/remove interrupts
  361. **************************************************************
  362. .OD.error:
  363. .OD.ok:
  364.         bset    #DDB_ONLINE,dd_flags(a5)    ; ready to accept packets
  365.         moveq   #0,d0
  366.         move.b  d0,IO_ERROR(a4)             ; complete the ioreq
  367.         move.b  #NT_REPLYMSG,LN_TYPE(a4)
  368.         addq.w  #1,LIB_OPENCNT(a5)          ; opened successfully
  369. .OD.done:
  370.  
  371.         IFGT    Printer
  372.  
  373.         bsr     DPutMsg
  374.         dc.l    EtherAddrMsg
  375.         move.l  dd_stationaddress+0(a5),d0
  376.         bsr     DPutHexL
  377.         move.w  dd_stationaddress+4(a5),d0
  378.         bsr     DPutHexW
  379.         bsr     DPutMsg
  380.         dc.l    EOLMsg
  381.  
  382.         bsr     DPutMsg
  383.         dc.l    DevOpenMsg
  384.  
  385.         ENDC
  386.  
  387.         subq.w  #1,LIB_OPENCNT(a5)          ; expunge protection
  388.         move.l  #0,d0
  389.         movem.l (A7)+,D2-D7/A2-A6
  390.         rts
  391.         
  392. EtherAddrMsg    STRING  "ETHERNET address: "
  393.  
  394. OpenUnitMsg     STRINGR "Open Unit no 0 "
  395. NoTagsMsg       STRINGR "Wrong number of tags"
  396.  
  397. ;===============================================================
  398. ;                 unit=Open Unit(device, ioreq, unitnum)
  399. ;                  d0              a0      a1     d0
  400. ;===============================================================
  401. ;
  402. ; Get the caller's buffer copy callback vectors
  403. ;
  404. ; NOTE: we only keep the vectors from the current caller
  405. ;
  406. ; do not access card - not need to have PCI page
  407. Open_Unit:
  408.         movem.l D2-D4/A2-A6,-(A7)
  409.         move.l  A0,A4                    ; A4 = device
  410.         move.l  A1,A5                    ; A5 = ioreq
  411.         tst.l   D0                       ; only unit 0 is supported
  412.         bne     .OU.error
  413.         
  414.         IFGT    Printer
  415.  
  416.         bsr     DPutMsg
  417.         dc.l    OpenUnitMsg
  418.  
  419.         ENDC
  420.  
  421.         move.l  ios2_buffermanagement(A5),D0  ; tag list supplied?
  422.         beq     .OU.ok
  423.         moveq   #0,D2                    ; d2 = number of required tags found
  424.         move.l  D0,A0                    ; a0 = tag list
  425. .OU.next_tag:
  426.         move.l  (A0)+,D0                 ; d0 = tag number
  427.         beq     .OU.got_tags                ; end of tag list?
  428.         move.l  (A0)+,D1                 ; d1 = tag value
  429.         cmp.l   #S2_COPYFROMBUFF,D0
  430.         beq.s   .OU.from                 ; tag_copyfrombuf ?
  431.         cmp.l   #S2_COPYTOBUFF,D0
  432.         bne.s   .OU.next_tag                ; tag_copytobuf ?
  433. .OU.to:
  434.         move.l  D1,dd_copytobuf(a4)      ; store function
  435.         addq.w  #1,D2                    ; got the tag
  436.         bra     .OU.next_tag
  437. .OU.from:
  438.         move.l  D1,dd_copyfrombuf(a4)    ; store function
  439.         addq.w  #1,D2                    ; got the tag
  440.         bra     .OU.next_tag
  441. .OU.got_tags:
  442.         subq.w  #2,D2                    ; got both tags ?
  443.         beq.s   .OU.ok
  444. .OU.error:
  445.         bsr     DPutMsg
  446.         dc.l    NoTagsMsg
  447.  
  448.         moveq   #0,d0                    ; return error
  449.         bra.s   .OU.done
  450. .OU.ok:
  451.         moveq   #1,d0                    ; return OK
  452. .OU.done:
  453.         movem.l (A7)+,D2-D4/A2-A6
  454.         rts
  455.  
  456. ExpungeDevMsg:  STRINGR "Expunge pcinet.device"
  457.  
  458.  
  459. ;============================================================
  460. ;                      Expunge Device
  461. ;============================================================
  462. ;
  463. ; called when system wants us to close down
  464. ;
  465. _DevExpunge:
  466.         movem.l d1-d4/a0-a6,-(sp)
  467.         move.l  a6,a5
  468.  
  469.         IFGT    Printer
  470.  
  471.         bsr     DPutMsg
  472.         dc.l    ExpungeDevMsg
  473.         
  474.         ENDC
  475.  
  476.         tst.w   LIB_OPENCNT(a5)
  477.         beq     .DE.DOExpunge
  478.         
  479.         bset    #LIBB_DELEXP,LIB_FLAGS(a5)
  480.         clr.l   d0
  481.         bra     .DE.exit
  482. .DE.DOExpunge
  483.         move.l  dd_seglist(a5),d2
  484.  
  485.         ; dealloc PCIMapping structs
  486.         move.l  dd_pcires(a5),a6
  487.         move.l  dd_mapping_main(a5),a1
  488.         tst.l   a1
  489.         beq     .DE.map1
  490.         jsr     PCIRFreePCIMapping(a6)
  491. .DE.map1:
  492.         move.l  dd_mapping_rx(a5),a1
  493.         tst.l   a1
  494.         beq     .DE.map2
  495.         jsr     PCIRFreePCIMapping(a6)
  496. .DE.map2:
  497.         move.l  dd_mapping_tx(a5),a1
  498.         tst.l   a1
  499.         beq     .DE.map3
  500.         jsr     PCIRFreePCIMapping(a6)
  501. .DE.map3:
  502.         move.l  dd_mapping_int(a5),a1
  503.         tst.l   a1
  504.         beq     .DE.map4
  505.         jsr     PCIRFreePCIMapping(a6)
  506. .DE.map4:
  507.  
  508.         ; now device typical code
  509.         move.l  a5,a1
  510.         move.l  execbase(pc),a6
  511.         jsr     _LVORemove(a6)
  512.         
  513.         ; free mem for device base
  514.         move.l  a5,a1
  515.         clr.l   d0
  516.         move.w  LIB_NEGSIZE(a5),d0
  517.         suba.l  d0,a1
  518.         add.w   LIB_POSSIZE(a5),d0
  519.         jsr     _LVOFreeMem(a6)
  520.         move.l  d2,d0
  521.         ; resource not require to close it
  522.  
  523. .DE.exit:
  524.         movem.l (sp)+,d1-d4/a0-a6
  525.         rts
  526.  
  527.  
  528. CloseDeviceMsg: STRINGR "Close pcinet.device"
  529.  
  530. ;============================================================
  531. ;                      Close Device
  532. ;============================================================
  533. ;
  534. ;  Seglist = CloseDevice(device, iob)
  535. ;    d0                    a6    A1
  536. ;
  537. Close_Device:
  538.         movem.l a5/a6,-(sp)
  539.         move.l  a6,a5
  540.         
  541.         IFGT    Printer
  542.         
  543.         bsr     DPutMsg
  544.         dc.l    CloseDeviceMsg
  545.         
  546.         ENDC
  547.  
  548.         move.l  #-1,d0
  549.         move.l  d0,IO_UNIT(a1)
  550.         move.l  d0,IO_DEVICE(a1)
  551.         
  552.         move.w  LIB_OPENCNT(a5),d0
  553.         beq.s   .CD.done                        ; already closed ?
  554.         subq.w  #1,d0
  555.         move.w  d0,LIB_OPENCNT(a5)
  556.         
  557.         ; disable interrupt 
  558.         move.l  dd_mapping_main(a5),a1
  559.         move.l  dd_pcires(a5),a6
  560.         jsr     PCIRObtainPCIPage(a6)
  561.         move.l  map_address(a1),a0
  562.         move.b  #0,nic_imr(a0)
  563.         move.b  #$FF,nic_isr(a0)
  564.         jsr     PCIRReleasePCIPage(a6)
  565.  
  566.         lea     dd_netinterrupt(a5),a1       ; init interrupts
  567.         move.l  dd_pciconfig(a5),a0
  568.         move.b  pcie_Cfg+pci_InterruptLine(a0),d0 
  569.         move.l  execbase(pc),a6
  570.         jsr     _LVORemIntServer(a6)
  571.         tst.w   LIB_OPENCNT(a5)
  572.         beq     .CD.done
  573.         clr.l   d0
  574.         movem.l (sp)+,a5/a6
  575.         rts
  576.  
  577. .CD.done:
  578.  
  579.         ; check DELexpunge flag
  580.         
  581.         btst    #LIBB_DELEXP,LIB_FLAGS(a5)
  582.         beq     .CD.Close
  583.         
  584.         bsr     _DevExpunge
  585.  
  586. .CD.Close
  587.         move.l  dd_seglist(a5),d0
  588.         movem.l (sp)+,a5/a6
  589.         rts
  590.  
  591. DevBegIOMsg:  STRING    "DevBeginIO Start unrecognized command: "
  592.  
  593.  
  594. ;===============================================================
  595. ;                       Dev_BeginIO(iob : a1, devptr : a6)
  596. ;===============================================================
  597. ; the entry point for all device commands
  598. ;
  599. _DevBeginIO:
  600.         move.w  IO_COMMAND(a1),d0
  601.         
  602.         move.b  #NT_MESSAGE,LN_TYPE(A1) ; make sure type is message
  603.         moveq   #0,d0
  604.         move.w  IO_COMMAND(A1),D0       ; get command number
  605.         cmp.w   #S2_END,D0
  606.         bhs.s   .DB.error               ; valid command?
  607.         lsl.w   #2,D0
  608.         move.l  cmds(PC,D0.w),D0        ; get command vector
  609.         bne.s   .DB.ok
  610. .DB.error:
  611.  
  612.         IFGT    Printer
  613.  
  614.         bsr     DPutMsg
  615.         dc.l    DevBegIOMsg
  616.         bsr     DPutHexW
  617.         bsr     DPutMsg
  618.         dc.l    EOLMsg
  619.         
  620.         ENDC
  621.         
  622.         move.b  #IOERR_NOCMD,IO_ERROR(A1)
  623.         bra     TermIO                  ; return invalid command
  624. .DB.ok:
  625.         clr.b   IO_ERROR(A1)            ; no errors yet
  626.  
  627.         ; most of the command dont access nic registers
  628.         ; so there is no sense to setup PCI page now
  629.  
  630.         move.l  D0,A0
  631.         jmp     (A0)                    ; jump to command
  632.  
  633.  
  634. ; command vector array   ( those marked '*' are commonly used by AmiTCP )
  635.  
  636. cmds:
  637.         dc.l    0                           ;  0
  638.         dc.l    0                           ;  1
  639.         dc.l    devcmd_read                 ;  2 = cmd_read               *
  640.         dc.l    devcmd_write                ;  3 = cmd_write              *
  641.         dc.l    0                           ;  4
  642.         dc.l    0                           ;  5
  643.         dc.l    0                           ;  6
  644.         dc.l    0                           ;  7
  645.         dc.l    devcmd_flush                ;  8 = cmd_flush
  646.         dc.l    devcmd_devicequery          ;  9 = S2_DEVICEQUERY         *
  647.         dc.l    devcmd_getstationaddress    ;  10= S2_GETSTATIONADDRESS   *
  648.         dc.l    devcmd_configinterface      ;  11= S2_CONFIGINTERFACE     *
  649.         dc.l    0                           ;  12
  650.         dc.l    0                           ;  13
  651.         dc.l    0                           ;  14= S2_ADDMULTICASTADDRESS
  652.         dc.l    0                           ;  15= S2_DELMULTICASTADDRESS
  653.         dc.l    0                           ;  16= S2_MULTICAST
  654.         dc.l    devcmd_broadcast            ;  17= S2_BROADCAST           *
  655.         dc.l    devcmd_tracktype            ;  18= S2_TRACKTYPE           *
  656.         dc.l    0                           ;  19= S2_UNTRACKTYPE
  657.         dc.l    0                           ;  20= S2_GETTYPESTATS
  658.         dc.l    0                           ;  21= S2_GETSPECIALSTATS
  659.         dc.l    0                           ;  22= S2_GETGLOBALSTATS
  660.         dc.l    devcmd_onevent              ;  23= S2_ONEVENT
  661.         dc.l    0                           ;  24= S2_READORPHAN
  662.         dc.l    devcmd_online               ;  25= S2_ONLINE
  663.         dc.l    devcmd_offline              ;  26= S2_OFFLINE
  664.  
  665.         dc.l    0
  666.  
  667.  
  668. DevAbortIOMsg:  STRINGR "_DevAbortIO Start"
  669.  
  670. ;====================================================================
  671. ;                              Abort_IO
  672. ;====================================================================
  673. ;
  674. ;                   try to cancel a pending ioreq
  675. ;
  676. ; no PCI access
  677. _DevAbortIO:
  678.         movem.l A2/A6,-(A7)
  679.         move.l  A1,A2
  680.  
  681.         IFGT    Printer
  682.         
  683.         bsr     DPutMsg
  684.         dc.l    DevAbortIOMsg
  685.         
  686.         ENDC
  687.         
  688.         moveq   #-1,D0                           ; assume failure
  689.         cmp.b   #NT_MESSAGE,LN_TYPE(A2)          ; only cancel queued ioreq's
  690.         bne.s   .DA.done
  691.         move.l  execbase(PC),A6
  692.         jsr     _LVODisable(A6)
  693.         move.l  A2,A1
  694.         jsr     _LVORemove(A6)                   ; remove ioreq from list
  695.         move.b  #IOERR_ABORTED,IO_ERROR(A2)
  696.         move.l  A2,A1
  697.         jsr     _LVOReplyMsg(A6)                 ; reply to originator's message
  698.         jsr     _LVOEnable(A6)
  699.         moveq   #0,D0                            ; aborted OK
  700. .DA.done:
  701.         movem.l (A7)+,A2/A6
  702.         rts
  703.  
  704.  
  705.  
  706. ;===========================================================
  707. ;                      termio(ioreq)
  708. ;                               a1
  709. ;===========================================================
  710. ;
  711. ; return completed ioreq to sender.
  712. ;
  713. ; no PCI access
  714. TermIOMsg       STRINGR "Terminate IO proc"
  715.  
  716. TermIO:
  717.         movem.l A2/A6,-(A7)
  718.         move.l  A1,A2
  719.         move.b  IO_ERROR(a1),d0             ; completed OK ?
  720.         beq.s   .TI.noerr
  721.         moveq   #0,d1
  722.         move.w  IO_COMMAND(a2),d1
  723.         move.l  IO_DEVICE(A2),A0
  724.         moveq   #S2EVENT_ERROR,D0
  725.         bsr     DoEvent                     ; create error event
  726. .TI.noerr:
  727.         move.b  #NT_REPLYMSG,LN_TYPE(A2)
  728.         btst    #IOB_QUICK,IO_FLAGS(A2)
  729.         bne.s   .TI.quick                      ; does sender need a reply ?
  730.         move.l  A2,A1
  731.         move.l  execbase(PC),A6
  732.         jsr     _LVOReplyMsg(A6)            ; not quick, so send reply
  733. .TI.quick
  734. .TI.done:
  735.  
  736.         IFGT    Printer
  737.  
  738.         bsr     DPutMsg
  739.         dc.l    TermIOMsg
  740.  
  741.         ENDC
  742.  
  743.         movem.l (A7)+,A2/A6
  744.         rts
  745.  
  746.  
  747.  
  748.  
  749. ;====================================================
  750. ;                     CMD_READ
  751. ;====================================================
  752. ;
  753. ; no PCI access
  754.  
  755. CMDReadMsg      STRINGR "devcmd_read proc"
  756.  
  757. devcmd_read:
  758.         movem.l A2/A3/A6,-(A7)
  759.         move.l  A1,A2                           ; A2 = ioreq
  760.  
  761.         IFGT    Printer
  762.  
  763.         bsr     DPutMsg
  764.         dc.l    CMDReadMsg
  765.  
  766.         ENDC
  767.  
  768.         move.l  IO_DEVICE(A2),A3
  769.         btst    #DDB_CONFIGURED,dd_flags(A3)    ; configured ?
  770.         bne.s   .dr.configured
  771.         move.b  #S2ERR_BAD_STATE,IO_ERROR(A2)
  772.         moveq   #S2WERR_NOT_CONFIGURED,D0
  773.         move.l  D0,ios2_wireerror(A2)           ; error, device is not configured
  774.         bra.s   .dr.error
  775. .dr.configured:
  776.         bclr    #IOB_QUICK,IO_FLAGS(A2)         ; must be queued
  777.         beq     .dr.readnoquick
  778.  
  779.         IFGT    Printer
  780.  
  781.         bsr     DPutMsg
  782.         dc.l    QuickIOMsg
  783.         
  784.         ENDC
  785.  
  786. .dr.readnoquick
  787.         move.l  execbase(PC),A6
  788.         jsr     _LVODisable(A6)
  789.         lea     dd_readlist(A3),A0
  790.         move.l  A2,A1
  791.         jsr     _LVOAddTail(A6)                 ; add ioreq to read queue
  792.         jsr     _LVOEnable(A6)
  793.         bra.s   .dr.done
  794. .dr.error:
  795.         move.l  A2,A1
  796.         bsr     TermIO                          ; terminate with error
  797. .dr.done:
  798.         movem.l (A7)+,A2/A3/A6
  799.         rts
  800.  
  801. QuickIOMsg      STRINGR "Unsuported quick IO read requested"
  802.  
  803. ;======================================================
  804. ;                      CMD_WRITE
  805. ;======================================================
  806. ;
  807. ; no PCI access - Couse
  808. CMDWriteMsg      STRINGR "devcmd_write proc"
  809.  
  810. devcmd_write:
  811.         movem.l A2/A3/A6,-(A7)
  812.         move.l  A1,A2                            ; A2 = ioreq
  813.  
  814.         IFGT    Printer
  815.  
  816.         bsr     DPutMsg
  817.         dc.l    CMDWriteMsg
  818.  
  819.         ENDC
  820.  
  821.         move.l  IO_DEVICE(A2),A3
  822.         btst    #DDB_CONFIGURED,dd_flags(A3)     ; configured ?
  823.         bne.s   .dw.configured
  824.         move.b  #S2ERR_BAD_STATE,IO_ERROR(A2)
  825.         moveq   #S2WERR_NOT_CONFIGURED,D0
  826.         move.l  D0,ios2_wireerror(A2)            ; error, not configured
  827.  
  828.         IFGT    Printer
  829.  
  830.         bsr     DPutMsg
  831.         dc.l    NotCFGMsg
  832.  
  833.         ENDC
  834.  
  835.         bra     .dw.error
  836. .dw.configured:
  837.         btst    #SANA2IOB_RAW,IO_FLAGS(A2)       ; raw packets ?
  838.         beq.s   .dw.cooked
  839.         move.l  ios2_datalength(A2),D1
  840.         cmp.l   #RAWPKT_SIZE,D1
  841.         bls.s   .dw.goodlen                         ; check packet size
  842.         bra.s   .dw.toobig
  843. .dw.cooked:
  844.         move.l  ios2_datalength(A2),D1
  845.         cmp.l   #ETHERPKT_SIZE,D1
  846.         bls.s   .dw.goodlen
  847. .dw.toobig:
  848.         move.b  #S2ERR_MTU_EXCEEDED,IO_ERROR(A2) ; oops! packet too big
  849.         clr.l   ios2_wireerror(A2)
  850.  
  851.         bsr     DPutMsg
  852.         dc.l    ToBigMsg
  853.  
  854.         bra     .dw.error
  855. .dw.goodlen:
  856.         bclr    #IOB_QUICK,IO_FLAGS(A2)          ; must be queued
  857.         move.l  execbase(PC),A6
  858.         jsr     _LVODisable(A6)
  859.         lea     dd_writelist(A3),A0
  860.         move.l  A2,A1
  861.         jsr     _LVOAddTail(A6)                  ; add ioreq to write queue
  862.         jsr     _LVOEnable(A6)
  863.         lea     dd_txint(A3),A1
  864.         jsr     _LVOCause(A6)                    ; start tx
  865.         bra.s   .dw.done
  866. .dw.error:
  867.         move.l  A2,A1
  868.         bsr     TermIO                           ; terminate with error
  869. .dw.done:
  870.         movem.l (A7)+,A2/A3/A6
  871.         rts
  872.  
  873. ToBigMsg        STRINGR "Package too big"
  874. NotCFGMsg       STRINGR "Interface not configured"
  875.  
  876. ;==============================================
  877. ;                CMD_FLUSH
  878. ;==============================================
  879. ;
  880. ; no PCI access
  881. CMDFlushMsg      STRINGR "devcmd_flush proc"
  882.  
  883.  
  884. devcmd_flush:
  885.         movem.l A1/A2/A6,-(A7)
  886.         move.l  IO_DEVICE(A1),A2
  887.  
  888.         IFGT    Printer
  889.  
  890.         bsr     DPutMsg
  891.         dc.l    CMDFlushMsg
  892.  
  893.         ENDC
  894.  
  895.         move.l  execbase(PC),A6
  896.         jsr     _LVODisable(A6)
  897.         bra.s   .df.flushreads
  898. .df.readloop:
  899.         move.l  D0,A1
  900.         move.b  #IOERR_ABORTED,IO_ERROR(A1)
  901.         jsr     _LVOReplyMsg(A6)             ; abort all Read requests
  902. .df.flushreads:
  903.         lea     dd_readlist(A2),A0
  904.         jsr     _LVORemHead(A6)
  905.         tst.l   D0
  906.         bne.s   .df.readloop
  907.         bra.s   .df.flushwrites
  908. .df.writeloop:
  909.         move.l  D0,A1
  910.         move.b  #IOERR_ABORTED,IO_ERROR(A1)
  911.         jsr     _LVOReplyMsg(A6)             ; abort all Write requests
  912. .df.flushwrites:
  913.         lea     dd_writelist(A2),A0
  914.         jsr     _LVORemHead(A6)
  915.         tst.l   D0
  916.         bne.s   .df.writeloop
  917.         bra.s   .df.flushevents
  918. .df.eventloop:
  919.         move.l  D0,A1                        ; abort all Event requests
  920.         move.b  #IOERR_ABORTED,IO_ERROR(A1)
  921.         jsr     _LVOReplyMsg(A6)
  922. .df.flushevents:
  923.         lea     dd_eventlist(A2),A0
  924.         jsr     _LVORemHead(A6)
  925.         tst.l   D0
  926.         bne.s   .df.eventloop
  927.         jsr     _LVOEnable(A6)
  928.         movem.l (A7)+,A1/A2/A6
  929.         bra     TermIO
  930.  
  931.  
  932. ;==============================================
  933. ;               CMD_ONLINE
  934. ;==============================================
  935. ;
  936. ;         Try to put device online
  937. ;
  938. ; do PCI access - main thread - call DoEvent
  939. CMDOnlineMsg      STRINGR "devcmd_online proc"
  940.  
  941.  
  942. devcmd_online:
  943.         movem.l d0/a0-a3/a6,-(a7)
  944.  
  945.         IFGT    Printer
  946.  
  947.         bsr     DPutMsg
  948.         dc.l    CMDOnlineMsg
  949.  
  950.         ENDC
  951.  
  952.         move.l  IO_DEVICE(a1),a2
  953.         btst    #DDB_CONFIGURED,dd_flags(a2)   ; won't go online unless configured!
  954.         beq.s   .do.error
  955.         bset    #DDB_ONLINE,dd_flags(a2)
  956.         bne.s   .do.done                          ; already online ?
  957.  
  958.         move.l  a1,a3
  959.  
  960.         move.l  dd_mapping_main(a2),a1
  961.         move.l  dd_pcires(a2),a6
  962.         jsr     PCIRObtainPCIPage(a6)
  963.         
  964.         move.l  map_address(a1),a0
  965.         move.b  dd_rcr(a2),nic_rcr(a0)         ; set receiver to normal mode
  966.  
  967.         jsr     PCIRReleasePCIPage(a6)
  968.  
  969.         IFGT    Printer
  970.  
  971.         bsr     DPutHexL
  972.         bsr     DPutMsg
  973.         dc.l    Rel1Msg
  974.  
  975.         ENDC
  976.         
  977.         move.l  a3,a1
  978.  
  979.         moveq   #S2EVENT_ONLINE,D0
  980.         bsr     DoEvent                        ; create ONLINE event
  981.         bra.s   .do.done
  982. .do.error:
  983.         move.b  #S2ERR_OUTOFSERVICE,IO_ERROR(a1)
  984.         moveq   #S2WERR_UNIT_OFFLINE,d0
  985.         move.l  d0,ios2_wireerror(a1)
  986. .do.done:
  987.         movem.l (a7)+,d0/a0-a3/a6
  988.         bra     TermIO
  989.  
  990. Rel1Msg         STRINGR " PCI errors - online"
  991.  
  992.  
  993. ;==============================================
  994. ;               CMD_OFFLINE
  995. ;==============================================
  996. ;
  997. ;           take device offline
  998. ;
  999. ; do PCI access - main thread - call DoEvent
  1000.  
  1001. CMDOfflineMsg      STRINGR "devcmd_offline proc"
  1002.  
  1003.  
  1004. devcmd_offline
  1005.         movem.l d0/a0-a3/a6,-(a7)
  1006.  
  1007.         IFGT    Printer
  1008.  
  1009.         bsr     DPutMsg
  1010.         dc.l    CMDOfflineMsg
  1011.  
  1012.         ENDC
  1013.  
  1014.         move.l  IO_DEVICE(a1),a2
  1015.         bclr    #DDB_ONLINE,dd_flags(a2)
  1016.         beq.s   .dof.done                          ; already offline ?
  1017.  
  1018.         move.l  a1,a3
  1019.  
  1020.         move.l  dd_mapping_main(a2),a1
  1021.         move.l  dd_pcires(a2),a6
  1022.         jsr     PCIRObtainPCIPage(a6)
  1023.         
  1024.         move.l  map_address(a1),a0
  1025.         move.b  #DSRC_MON,nic_rcr(a0)          ; set receiver to monitor mode
  1026.  
  1027.         jsr     PCIRReleasePCIPage(a6)
  1028.  
  1029.         IFGT    Printer
  1030.  
  1031.         bsr     DPutHexL
  1032.         bsr     DPutMsg
  1033.         dc.l    Rel2Msg
  1034.  
  1035.         ENDC
  1036.         
  1037.         move.l  a3,a1
  1038.  
  1039.         moveq   #S2EVENT_OFFLINE,D0
  1040.         bsr     DoEvent                        ; create OFFLINE event
  1041. .dof.done:
  1042.         movem.l (a7)+,d0/a0-a3/a6
  1043.         bra     TermIO
  1044.  
  1045. Rel2Msg         STRINGR " PCI errors - offline"
  1046.  
  1047. ;==============================================
  1048. ;               CMD_ONEVENT
  1049. ;==============================================
  1050. ;
  1051. ;         queue up event requests
  1052. ;
  1053. ; no PCI access
  1054. CMDOneventMsg      STRINGR "devcmd_onevent proc"
  1055.  
  1056.  
  1057. devcmd_onevent:
  1058.         movem.l a1/a6,-(a7)
  1059.  
  1060.         IFGT    Printer
  1061.  
  1062.         bsr     DPutMsg
  1063.         dc.l    CMDOneventMsg
  1064.  
  1065.         ENDC
  1066.  
  1067.         move.l  IO_DEVICE(a1),a0
  1068.         bclr    #IOB_QUICK,IO_FLAGS(a1)     ; must be queued
  1069.         move.l  execbase(PC),A6
  1070.         jsr     _LVODisable(A6)
  1071.         lea     dd_eventlist(A0),A0
  1072.         jsr     _LVOAddTail(A6)             ; add ioreq to event queue
  1073.         jsr     _LVOEnable(A6)
  1074.         movem.l (a7)+,a1/a6
  1075.         bra     TermIO
  1076.  
  1077.  
  1078.  
  1079.  
  1080. ;==============================================
  1081. ;             CMD_DEVICEQUERY
  1082. ;==============================================
  1083. ;
  1084. ; no PCI access
  1085.  
  1086. CMDDeviceQueryMsg      STRINGR "devcmd_devicequery proc"
  1087.  
  1088. devcmd_devicequery:
  1089.         move.l  A1,-(A7)
  1090.  
  1091.         IFGT    Printer
  1092.  
  1093.         bsr     DPutMsg
  1094.         dc.l    CMDDeviceQueryMsg
  1095.  
  1096.         ENDC
  1097.  
  1098.         move.l  ios2_statdata(A1),A0    ; a0 = caller's buffer
  1099.         move.l  (A0),D1                 ; D1 = buffer size
  1100.         move.l  size_supplied(pc),D0
  1101.         cmp.l   D0,D1                   ; enough space to store info?
  1102.         bhs.s   .dq.get
  1103.         clr.l   S2DQ_SIZESUPPLIED(A0)   ; nope!
  1104.         bra.s   .dq.done
  1105. .dq.get:
  1106.         lea     S2DQ_SIZESUPPLIED(A0),A1
  1107.         lea     size_supplied(pc),A0
  1108.         subq.l  #4,D0                   ; skip bytes_available
  1109.         bra.s   .dq.copy
  1110. .dq.copyloop:
  1111.         move.b  (A0)+,(A1)+             ; copy info to caller's buffer
  1112. .dq.copy:
  1113.         dbf     D0,.dq.copyloop
  1114. .dq.done:
  1115.         move.l  (A7)+,A1
  1116.         bra     TermIO
  1117.  
  1118.  
  1119.  
  1120. ;==============================================
  1121. ;           CMD_GETSTATIONADDRESS
  1122. ;==============================================
  1123. ;
  1124. ; no PCI access
  1125. CMDGetstataddrMsg      STRINGR "devcmd_getstationaddress proc"
  1126.  
  1127.  
  1128. devcmd_getstationaddress:
  1129.         move.l  A1,-(A7)
  1130.  
  1131.         IFGT    Printer
  1132.  
  1133.         bsr     DPutMsg
  1134.         dc.l    CMDGetstataddrMsg
  1135.  
  1136.         ENDC
  1137.  
  1138.         move.l  IO_DEVICE(A1),A0
  1139.         lea     dd_stationaddress(A0),A0
  1140.         move.l  A0,D1
  1141.         lea     ios2_srcaddr(A1),A1
  1142.         move.w  #ETHER_ADDR_SIZE-1,D0
  1143. .dga.copysrc:
  1144.         move.b  (A0)+,(A1)+             ; source address = station address
  1145.         dbf     d0,.dga.copysrc
  1146.         move.l  (A7),A1
  1147.         lea     ios2_dstaddr(A1),A1
  1148.         move.w  #ETHER_ADDR_SIZE-1,D0
  1149.         move.l  D1,A0
  1150. .dga.copydst:
  1151.         moveq   #0,d1
  1152.         move.b  (A0)+,d1
  1153.         move.b  d1,(A1)+                ; dest address = station address
  1154.         dbf     d0,.dga.copydst
  1155.         move.l  (A7)+,A1
  1156.         bra     TermIO
  1157.  
  1158.  
  1159. ;==============================================
  1160. ;             CMD_CONFIGINTERFACE
  1161. ;==============================================
  1162. ;
  1163. ; NOTE: a default station address has already
  1164. ;       been set by init_nic
  1165. ;
  1166. ; do PCI access - main thread - disable 
  1167.  
  1168. CMDConfigMsg      STRINGR "devcmd_configinterface proc"
  1169.  
  1170. devcmd_configinterface:
  1171.         movem.l d0/a0-a3/a6,-(sp)
  1172.  
  1173.         IFGT    Printer
  1174.  
  1175.         bsr     DPutMsg
  1176.         dc.l    CMDConfigMsg
  1177.  
  1178.         ENDC
  1179.  
  1180.         move.l  IO_DEVICE(A1),A2
  1181.         move.l  ios2_srcaddr(a1),d0
  1182.         ble     .dci.done                          ; check for valid address
  1183.         move.l  d0,dd_stationaddress(a2)
  1184.         move.w  ios2_srcaddr+4(a1),dd_stationaddress+4(a2)
  1185.         move.l  execbase(pc),a6
  1186.         jsr     _LVODisable(a6)
  1187.  
  1188.         move.l  a1,a3
  1189.  
  1190.         move.l  dd_mapping_main(a2),a1
  1191.         move.l  dd_pcires(a2),a6
  1192.         jsr     PCIRStorePCIPage(a6)
  1193.         move.l  map_address(a1),a0
  1194.  
  1195.         move.b  nic_cr(a0),d1                       ; remember current command
  1196.         delay
  1197.         move.b  #DSCM_NODMA|DSCM_PG1,nic_cr(a0)     ; select bank 1
  1198.         delay
  1199.         move.b  dd_stationaddress+0(a2),nic_par0(a0)
  1200.         delay
  1201.         move.b  dd_stationaddress+1(a2),nic_par1(a0)
  1202.         delay
  1203.         move.b  dd_stationaddress+2(a2),nic_par2(a0)
  1204.         delay                                        ; set station address
  1205.         move.b  dd_stationaddress+3(a2),nic_par3(a0)
  1206.         delay
  1207.         move.b  dd_stationaddress+4(a2),nic_par4(a0)
  1208.         delay
  1209.         move.b  dd_stationaddress+5(a2),nic_par5(a0)
  1210.         delay
  1211.         move.b  d1,nic_cr(a0)                  ; restore command
  1212.         
  1213.         jsr     PCIRRestorePCIPage(a6)
  1214.  
  1215.         IFGT    Printer
  1216.  
  1217.         bsr     DPutHexL
  1218.         bsr     DPutMsg
  1219.         dc.l    Rel3Msg
  1220.  
  1221.         ENDC
  1222.         
  1223.         move.l  a3,a1
  1224.  
  1225.         move.l  execbase(pc),a6
  1226.         jsr     _LVOEnable(a6)
  1227.         
  1228.         bset    #DDB_CONFIGURED,dd_flags(a2)   ; now configured
  1229. .dci.done:
  1230.         movem.l (sp)+,d0/a0-a3/a6
  1231.         bra     TermIO
  1232.  
  1233. Rel3Msg         STRINGR " PCI errors - config interface"
  1234.  
  1235. ;==============================================
  1236. ;              CMD_BROADCAST
  1237. ;==============================================
  1238. ;
  1239. ; no PCI access
  1240. CMDbroadcastMsg      STRINGR "devcmd_broadcast proc"
  1241.  
  1242.  
  1243. devcmd_broadcast:
  1244.  
  1245.         IFGT    Printer
  1246.  
  1247.         bsr     DPutMsg
  1248.         dc.l    CMDbroadcastMsg
  1249.  
  1250.         ENDC
  1251.  
  1252.         move.w  #ETHER_ADDR_SIZE-1,D0
  1253.         moveq   #0,d1
  1254. .db.loop:
  1255.         move.b  #255,ios2_dstaddr(a1,d1.w)    ; dest address = BROADCAST
  1256.         addq.w  #1,d1
  1257.         dbf     d0,.db.loop
  1258. .db.doit:
  1259.         bra     devcmd_write
  1260.  
  1261.  
  1262.  
  1263. ;============================================
  1264. ;              CMD_TRACKTYPE
  1265. ;============================================
  1266. ;
  1267. ; This function adds a packet type to the
  1268. ; list of those that are being tracked.
  1269. ;
  1270. ; no PCI access
  1271. CMDTrackTypeMsg      STRINGR "devcmd_tracktype proc"
  1272.  
  1273.  
  1274. devcmd_tracktype:
  1275.  
  1276.         IFGT    Printer
  1277.  
  1278.         bsr     DPutMsg
  1279.         dc.l    CMDTrackTypeMsg
  1280.  
  1281.         ENDC
  1282.  
  1283.         bra     TermIO    ; but we won't actually track anything
  1284.  
  1285.  
  1286. ;=========================================
  1287. ;      doevent(device, event)
  1288. ;                a0     d0
  1289. ;=========================================
  1290. ;
  1291. ; called when an 'important' event occurs
  1292. ;
  1293. ; no PCI access
  1294. doeventmsg      STRINGR "Do event proc"
  1295.  
  1296.  
  1297. DoEvent:
  1298.         movem.l D2/A2/A6,-(A7)
  1299.         move.l  D0,D2
  1300.  
  1301.         IFGT    Printer
  1302.         
  1303.         bsr     DPutMsg
  1304.         dc.l    doeventmsg
  1305.         
  1306.         ENDC
  1307.         
  1308.         move.l  dd_eventlist(A0),A2     ; get first ioreq
  1309.         move.l  execbase(PC),A6
  1310.         jsr     _LVODisable(A6)         ; exclusive access to list required
  1311.         bra.s   .de.start
  1312. .de.loop:
  1313.         move.l  ios2_wireerror(A2),D0
  1314.         and.l   D2,D0                   ; should this ioreq be completed?
  1315.         beq.s   .de.next
  1316.         move.l  D0,ios2_wireerror(A2)   ; clear the event
  1317.         move.l  A2,A1
  1318.         jsr     _LVORemove(A6)          ; remove ioreq from list
  1319.         move.l  A2,A1
  1320.         bsr     TermIO                  ; return ioreq to owner
  1321. .de.next:
  1322.         move.l  (A2),A2                 ; next ioreq
  1323. .de.start:
  1324.         tst.l   (A2)                    ; last ioreq ?
  1325.         bne.s   .de.loop
  1326. .de.done:
  1327.         jsr     _LVOEnable(A6)          ; other tasks now allowed to access list
  1328.         movem.l (A7)+,D2/A2/A6
  1329.         rts
  1330.  
  1331. ;======================
  1332. ;  delay approx 1.5mS
  1333. ;======================
  1334. ;
  1335.  
  1336.  
  1337. delay1500:
  1338.         move.l   D0,-(A7)
  1339.         move.w   #1500,D0
  1340. .del.loop:
  1341.         tst.b    $bfe001       ; wait 1uS
  1342.         dbf      D0,.del.loop
  1343.         move.l   (A7)+,D0
  1344.         rts
  1345.  
  1346.  
  1347.  
  1348.  
  1349.  
  1350. ;==================================================================
  1351. ;        RemoteRead(buffer, nicbuffer, length, iobase)
  1352. ;                     a1       d0.w     d1.w    a4
  1353. ;==================================================================
  1354. ;
  1355. ; Get a copy of data stored in the network card's onboard RAM.
  1356. ;
  1357. ;  buffer     = Amiga RAM
  1358. ;
  1359. ;  nicbuffer  = 16 bit address in card memory
  1360. ;
  1361. ; do PCI access - a4 IOBase
  1362.  
  1363. RRMsg           STRING  "RemoteRead: "
  1364.  
  1365. RemoteRead:
  1366.  
  1367.         IFGT    Printer
  1368.  
  1369.         bsr     DPutMsg
  1370.         dc.l    RRMsg
  1371.  
  1372.  
  1373.         movem.l d0/d1,-(sp)
  1374.         clr.l   d0
  1375.         move.w  d1,d0
  1376.         bsr     DPutHexW
  1377.         bsr     DPutMsg
  1378.         dc.l    EOLMsg
  1379.         movem.l (sp)+,d0/d1
  1380.         bsr     DPutMem
  1381.         
  1382.         ENDC
  1383.  
  1384.         addq.w  #1,D1                   ; bump up count to even value
  1385.         bclr    #0,d1
  1386.         swap    d1
  1387.         delay
  1388.         move.b  nic_cr(a4),d1           ; save old command
  1389.         swap    d1
  1390.         delay
  1391.         move.b  #DSCM_NODMA|DSCM_START,nic_cr(A4)  ; select bank 0
  1392.         delay
  1393.         move.b  D1,nic_rbcr0(A4)        ;   set count.lo
  1394.         ror.w   #8,D1
  1395.         delay
  1396.         move.b  D1,nic_rbcr1(A4)        ;   set count.hi
  1397.         delay
  1398.         move.b  D0,nic_rsar0(A4)        ;   set address.lo
  1399.         ror.w   #8,D0
  1400.         delay
  1401.         move.b  D0,nic_rsar1(A4)        ;   set address.hi
  1402.         delay
  1403.         move.b  #DSCM_RREAD|DSCM_START,nic_cr(A4) ; request Remote Read
  1404.         ror.w   #8,D1
  1405.         
  1406.         asr.w   #1,d1
  1407.  
  1408.         ; d1 - licznik slow
  1409.         lea     nic_data(a4),a0         ; number of 'move.w' opcodes
  1410.         bra     .RR.dmqdbf
  1411.  
  1412. .RR.dmaread:
  1413.         move.w  (A0),(A1)+              ; read data words from nic
  1414. .RR.dmqdbf:
  1415.         dbf.w   d1,.RR.dmaread
  1416.  
  1417.         move.b  #DSIS_RDC,nic_isr(A4)   ; Remote DMA Complete
  1418.         swap    d1
  1419.         delay
  1420.         move.b  d1,nic_cr(a4)           ; restore old command
  1421.         rts
  1422.  
  1423.  
  1424.  
  1425. ;=================================================================
  1426. ;         RemoteWrite( buffer, nicbuffer, count, IObase )
  1427. ;                        a1      d0.w     d1.w    a4
  1428. ;=================================================================
  1429. ;
  1430. ;      Puts data into the network card's onboard RAM
  1431. ;
  1432. ;  buffer    = Amiga memory
  1433. ;
  1434. ;  nicbuffer = 16 bit address in card RAM
  1435. ;
  1436. ;
  1437. ; do PCI access - A4 - IOBase
  1438.  
  1439. RWMsg           STRING  "RemoteWrite: "
  1440.  
  1441. RemoteWrite:
  1442.  
  1443.         IFGT    Printer
  1444.  
  1445.         bsr     DPutMsg
  1446.         dc.l    RWMsg
  1447.  
  1448.         movem.l d0/d1,-(sp)
  1449.         clr.l   d0
  1450.         move.w  d1,d0
  1451.         bsr     DPutHexW
  1452.         bsr     DPutMsg
  1453.         dc.l    EOLMsg
  1454.         movem.l (sp)+,d0/d1
  1455.         bsr     DPutMem
  1456.  
  1457.         ENDC
  1458.  
  1459.  
  1460.         addq.w  #1,D1
  1461.         bclr    #0,D1                   ; bump up count to even value
  1462.         swap    d1
  1463.         delay
  1464.         move.b  nic_cr(a4),d1           ; save old command
  1465.         swap    d1
  1466.         delay
  1467.         move.b  #DSIS_RDC,nic_isr(A4)   ; remote DMA complete
  1468.         delay
  1469.         move.b  #DSCM_NODMA|DSCM_START,nic_cr(A4) ; select bank 0
  1470.         delay
  1471.         move.b  D0,nic_rsar0(A4)        ; set address.lo
  1472.         lsr.w   #8,D0
  1473.         delay
  1474.         move.b  D0,nic_rsar1(A4)        ; set address.hi
  1475.         delay
  1476.         move.b  D1,nic_rbcr0(A4)        ; set count.lo
  1477.         ror.w   #8,D1
  1478.         delay
  1479.         move.b  D1,nic_rbcr1(A4)        ; set count.hi
  1480.         delay
  1481.         move.b  #DSCM_START|DSCM_RWRITE,nic_cr(A4) ; request remote write
  1482.         ror.w   #8,D1
  1483.         lea     nic_data(a4),a0
  1484.  
  1485.         asr.w   #1,d1
  1486.         ; d1 - licznik transmisji slow
  1487.         ; it was using rept 800 move.w (a1)+,(a0)
  1488.         ; 68020 have cache - loop is more efective
  1489.         bra     .RW.dmaread.dbf
  1490.  
  1491. .RW.dmaread:
  1492.         move.w  (A1)+,(A0)
  1493. .RW.dmaread.dbf:
  1494.         dbf     d1,.RW.dmaread
  1495.  
  1496.         move.w  #30000,D0               ; set timeout
  1497. .RW.check:
  1498.         delay
  1499.         move.b  nic_isr(A4),d1          ; wait for remote DMA complete
  1500.         and.b   #DSIS_RDC,d1
  1501.         bne.s   .RW.ok
  1502.         dbf     D0,.RW.check
  1503.         moveq   #1,D0                   ; timed out error
  1504.         bsr     DPutMsg
  1505.         dc.l    RWTimeoutMsg
  1506.         bra.s   .RW.done
  1507. .RW.ok:
  1508.         moveq   #0,D0                   ; OK
  1509. .RW.done:
  1510.         delay
  1511.         move.b  #DSIS_RDC,nic_isr(a4)   ; Remote DMA complete
  1512.         swap    d1
  1513.         delay
  1514.         move.b  d1,nic_cr(a4)           ; restore old command
  1515.         rts
  1516.  
  1517. RWTimeoutMsg    STRINGR "Timeout error in RemoteWRITE"
  1518.  
  1519. ;=========================================================
  1520. ;                      reset_nic(IOBase : a4)
  1521. ;=========================================================
  1522. ;
  1523. ; do PCI access - a4 IOBase
  1524. reset_nic:
  1525.         delay
  1526.         move.b  nic_rst(A4),D0                   ; start reset pulse
  1527.         delay
  1528.         move.b  D0,nic_rst(A4)                   ; end reset pulse
  1529.         delay
  1530.         move.b  #DSCM_NODMA|DSCM_STOP,nic_cr(A4) ; stop controller
  1531.         bsr     delay1500                        ; wait 1.5mS
  1532.         move.b  #$ff,nic_isr(A4)                 ; clear all nic ints
  1533.         rts
  1534.  
  1535.  
  1536. ;========================================================================
  1537. ;                           init_nic(device)
  1538. ;                                      a1
  1539. ;========================================================================
  1540. ;
  1541. ;            set up the network card for online operation
  1542. ;
  1543. ; Here we also get the hardware station address from the nic's ROM. The
  1544. ; CNet card sometimes doesn't read its ROM correctly, so in this case we
  1545. ; use a fixed address instead.
  1546. ;
  1547. ; do PCI access - disable - calkowicie
  1548.  
  1549. InitNicMsg      STRINGR "Init NIC"
  1550. WindowAddMsg    STRING "PCI window address: "
  1551. EOLMsg          STRINGR " "
  1552. ErrorInitPCIMsg STRINGR " PCI state restored after error"
  1553. SuccessInitPCIMsg STRINGR " PCI state restored after success"
  1554. BadETHAddrMsg   STRINGR "BAD ETHERNET ADDRESS !!!! - using defaults"
  1555.  
  1556. init_nic:
  1557.         movem.l D0-D2/A0-A6,-(A7)
  1558.         move.l  A1,A5                             ; a5 = device data
  1559.  
  1560.         IFGT    Printer
  1561.  
  1562.         bsr     DPutMsg
  1563.         dc.l    InitNicMsg
  1564.  
  1565.         ENDC
  1566.  
  1567.         move.l  execbase(PC),A6
  1568.         jsr     _LVODisable(A6)                   ; ignore ints while setting up
  1569.         btst    #DDB_NICUP,dd_flags(a5)
  1570.         bne     .in.ok                               ; already initialised ?
  1571.         move.b  #DSDC_WTS|DSDC_FT1|DSDC_BMS,dd_dcr(A5)  ; Word Xfer, FIFO, Burst
  1572.         move.b  #DSRC_AB,dd_rcr(A5)                     ; accept broadcast packets
  1573.         move.b  #INTMASK,dd_imr(A5)                     ; accept useful interrupts
  1574.  
  1575.         move.l  dd_mapping_main(a5),a1
  1576.         move.l  dd_pcires(a5),a6
  1577.         jsr     PCIRStorePCIPage(a6)
  1578.         move.l  map_address(a1),a4
  1579.  
  1580.         IFGT    Printer
  1581.  
  1582.         bsr     DPutMsg
  1583.         dc.l    WindowAddMsg
  1584.  
  1585.         move.l  a4,d0
  1586.         bsr     DPutHexL
  1587.         bsr     DPutMsg
  1588.         dc.l    EOLMsg
  1589.  
  1590.         ENDC
  1591.  
  1592.         bsr     reset_nic                         ; reset the controller
  1593.         delay
  1594.         move.b  nic_cr(A4),D0                     ; get command
  1595.         cmp.b   #DSCM_NODMA|DSCM_STOP,d0
  1596.         bne     .in.error                            ; is it correct ?
  1597.         delay
  1598.         move.b  dd_dcr(A5),nic_dcr(A4)            ; set data configuration register
  1599.         delay
  1600.         move.b  #0,nic_rbcr0(A4)                  ; clear remote byte count
  1601.         delay
  1602.         move.b  #0,nic_rbcr1(A4)                  ;         ''
  1603.         delay
  1604.         move.b  #DSRC_MON,nic_rcr(A4)             ; set rx to monitor mode
  1605.         delay
  1606.         move.b  #DSTC_LB0,nic_tcr(A4)             ; set tx to loopback mode 1
  1607.         delay
  1608.         move.b  #(RBUFEND/256)-1,nic_bnry(A4)     ; set boundary page
  1609.         delay
  1610.         move.b  #RBUF/256,nic_pstart(A4)          ; set start of rx ring buffer
  1611.         delay
  1612.         move.b  #RBUFEND/256,nic_pstop(A4)        ; set end of rx ring buffer
  1613.         delay
  1614.         move.b  #$ff,nic_isr(a4)                  ; clear all interrupts
  1615.         delay
  1616.         move.b  #0,nic_imr(a4)                    ; no interrupts allowed
  1617.         delay
  1618.         move.b  nic_rsr(a4),d0
  1619.         delay
  1620.         move.b  nic_ncr(a4),d0
  1621.         delay
  1622.         move.b  nic_cntr0(a4),d0                  ; read status registers
  1623.         delay
  1624.         move.b  nic_cntr1(a4),d0
  1625.         delay
  1626.         move.b  nic_cntr2(a4),d0
  1627.         delay
  1628.         move.b  #ETHER_ADDR_SIZE*2,nic_rbcr0(A4)  ; byte count low = (words)
  1629.         delay
  1630.         move.b  #0,nic_rbcr1(A4)                  ; byte count high = 0
  1631.         delay
  1632.         move.b  #0,nic_rsar0(A4)                  ; remote start addr low = 0 (ROM)
  1633.         delay
  1634.         move.b  #0,nic_rsar1(A4)                  ; remote start addr high = 0 (ROM)
  1635.         delay
  1636.         move.b  #DSCM_RREAD,nic_cr(A4)            ; start remote read to get
  1637.         delay                                     ; station address from ROM
  1638.         lea     dd_romstationaddress(a5),A0
  1639.         move.w  #ETHER_ADDR_SIZE-1,D0
  1640. .in.getaddr:
  1641.         move.b  nic_data(A4),(A0)+                ; get ROM station address
  1642.         dbf     D0,.in.getaddr                       ; NOTE: 'move.b' as ROM is 8 bit
  1643.         move.w  #30000,d1
  1644. .in.waitloop:
  1645.         delay
  1646.         move.b  nic_isr(A4),d0
  1647.         and.b   #DSIS_RDC,d0                      ; wait for remote DMA complete
  1648.         dbne    d1,.in.waitloop
  1649.         tst.w   d0
  1650.         beq     .in.error                            ; error if timed out
  1651.         delay
  1652.         move.b  #DSIS_RDC,nic_isr(A4)             ; clear remote DMA complete int
  1653.         lea     dd_romstationaddress(a5),a0
  1654.         btst    #7,(a0)
  1655.         bne.s   .in.badaddr                          ; good station address ?
  1656.         move.l  2(a0),d0
  1657.         beq.s   .in.badaddr
  1658.         cmp.l   #-1,d0
  1659.         bne.s   .in.gotstation
  1660. .in.badaddr:
  1661.         bsr     DPutMsg
  1662.         dc.l    BadETHAddrMsg
  1663.         
  1664.         lea     default_address(pc),a0            ; use known good station address
  1665. .in.gotstation:
  1666.         lea     dd_stationaddress(a5),a1
  1667.         moveq   #ETHER_ADDR_SIZE-1,d0
  1668. .in.copyaddr:
  1669.         move.b  (a0)+,(a1)+                        ; copy address to device data
  1670.         dbf     d0,.in.copyaddr
  1671.         delay
  1672.         move.b  #DSCM_NODMA|DSCM_PG1|DSCM_STOP,nic_cr(A4) ; select bank 1
  1673.         delay
  1674.         move.b  dd_stationaddress+0(a5),nic_par0(a4)
  1675.         delay
  1676.         move.b  dd_stationaddress+1(a5),nic_par1(a4)
  1677.         delay
  1678.         move.b  dd_stationaddress+2(a5),nic_par2(a4)
  1679.         delay                                             ; set station address
  1680.         move.b  dd_stationaddress+3(a5),nic_par3(a4)
  1681.         delay
  1682.         move.b  dd_stationaddress+4(a5),nic_par4(a4)
  1683.         delay
  1684.         move.b  dd_stationaddress+5(a5),nic_par5(a4)
  1685.         delay
  1686.         move.b  #RBUF/256,nic_curr(A4)         ; set current page for rx
  1687.         move.b  #DSCM_NODMA|DSCM_START,d0
  1688.         delay
  1689.         move.b  d0,nic_cr(A4)                  ; start controller
  1690.         delay
  1691.         cmp.b   nic_cr(A4),D0
  1692.         bne     .in.error                         ; command accepted ?
  1693.         delay
  1694.         move.b  dd_rcr(A5),nic_rcr(A4)         ; normal rx mode
  1695.         delay
  1696.         move.b  #0,nic_tcr(A4)                 ; loopback mode off
  1697.         delay
  1698.         move.b  #TBUF/256,nic_tpsr(a4)         ; init tx start page
  1699.         delay
  1700.         move.b  #$ff,nic_isr(A4)               ; clear all interrupts
  1701.         delay
  1702.         move.b  dd_imr(A5),nic_imr(A4)         ; enable nic interrupts
  1703.  
  1704.         move.l  dd_mapping_main(a5),a1
  1705.         move.l  dd_pcires(a5),a6
  1706.         jsr     PCIRRestorePCIPage(a6)
  1707.         
  1708.         IFGT    Printer
  1709.  
  1710.         bsr     DPutHexL
  1711.         bsr     DPutMsg
  1712.         dc.l    SuccessInitPCIMsg        
  1713.  
  1714.         ENDC
  1715.  
  1716. .in.ok        
  1717.         bset    #DDB_NICUP,dd_flags(a5)        ; nic is initialised
  1718.         moveq   #0,D0
  1719.         bra.s   .in.done                          ; return OK
  1720.  
  1721. .in.error:
  1722.         bsr     reset_nic                      ; reset nic after malfunction
  1723.         move.l  dd_mapping_main(a5),a1
  1724.         move.l  dd_pcires(a5),a6
  1725.         jsr     PCIRRestorePCIPage(a6)
  1726.         
  1727.         bsr     DPutHexL
  1728.         bsr     DPutMsg
  1729.         dc.l    ErrorInitPCIMsg        
  1730. .in.bad:
  1731.  
  1732.         moveq   #-1,D0                         ; return error
  1733. .in.done:
  1734.         move.l  execbase(pc),a6
  1735.         jsr     _LVOEnable(A6)                 ; allow interrupt processing
  1736.         movem.l (A7)+,D0-D2/A0-A6
  1737.         rts
  1738.  
  1739.  
  1740. ;========================================================
  1741. ;                 txintcode(device)
  1742. ;                             a1
  1743. ;========================================================
  1744. ;
  1745. ;  send packets to network card. packets will be put
  1746. ;  into the card's onboard 16 bit ram, and then
  1747. ;  transmitted to the wire.
  1748. ;
  1749. ; do PCI access - interrupt function
  1750. TXIntMsg        STRINGR "service tx interrupt"
  1751. txintcode:
  1752.         movem.l D4-D7/A2-A6,-(A7)
  1753.         move.l  A1,A5                      ; a5 = device
  1754.                                            ; a4 = IOBase
  1755.  
  1756.         IFGT    Printer
  1757.  
  1758.         bsr     DPutMsg
  1759.         dc.l    TXIntMsg
  1760.         
  1761.         ENDC
  1762.  
  1763. ; StorePCIPage
  1764.         move.l  dd_mapping_tx(a5),a1
  1765.         move.l  dd_pcires(a5),a6
  1766.         jsr     PCIRStorePCIPage(a6)
  1767.         
  1768.         move.l  map_address(a1),a4
  1769.  
  1770. .ti.next:
  1771.         btst    #DDB_TX,dd_flags(a5)  ; quit if tx in progress (status int
  1772.         bne     .ti.done              ; will restart us when tx complete)
  1773. .ti.getreq:
  1774.         lea     dd_writelist(A5),A0
  1775.         move.l  execbase(pc),a6            ; remove top ioreq
  1776.         jsr     _LVORemHead(A6)
  1777.         tst.l   D0                         ; any ioreqs to process?
  1778.         beq     .ti.done
  1779.         move.l  D0,A3                      ; A3 = ioreq
  1780.         lea     txbuffer,A1                ; A1 = our internal packet buffer
  1781.         btst    #SANA2IOB_RAW,IO_FLAGS(A3) ; raw packets?
  1782.         beq.s   .ti.notraw
  1783.         move.l  ios2_datalength(A3),D6     ; raw packet is full length
  1784.         bra.s   .ti.send
  1785. .ti.notraw:
  1786.         lea     ios2_dstaddr(A3),A0
  1787.         moveq   #ETHER_ADDR_SIZE-1,D0
  1788. .ti.copy1:
  1789.         move.b  (A0)+,(A1)+                ; insert dest stationaddr into packet
  1790.         dbra    D0,.ti.copy1
  1791.         lea     dd_stationaddress(A5),A0
  1792.         moveq   #ETHER_ADDR_SIZE-1,D0
  1793. .ti.copy2:
  1794.         move.b  (A0)+,(A1)+                ; insert src address into packet
  1795.         dbra    D0,.ti.copy2
  1796.         move.l  ios2_packettype(A3),D0     ; insert packettype into packet
  1797.         move.w  D0,(A1)+
  1798.         moveq   #ether_data,D6
  1799.         add.l   ios2_datalength(A3),D6     ; d6 = length of header + data
  1800. .ti.send:
  1801.         move.l  dd_copyfrombuf(a5),a2
  1802.         move.l  a1,a0
  1803.         move.l  ios2_data(A3),A1
  1804.         move.l  ios2_datalength(A3),D0
  1805.         jsr     (a2)                       ; call copyfrombuf
  1806.         moveq   #ETHER_MIN_LEN,D0
  1807.         cmp.l   D0,D6
  1808.         bge.s   .ti.min                    ; d6 adjusted to legal packet size
  1809.         move.l  D0,D6
  1810. .ti.min:
  1811.         move.l  D6,D1
  1812.         move.w  #TBUF,d0
  1813.         lea     txbuffer,A1
  1814.  
  1815.         bsr     RemoteWrite                ; put packet into nic tx buffer
  1816.         tst.l   D0
  1817.         bne.s   .ti.termio
  1818.         move.l  execbase(PC),A6            ; disable interrupts during tx setup
  1819.         jsr     _LVODisable(A6)
  1820.         bset    #DDB_TX,dd_flags(A5)       ; set our "buffer full" flag
  1821.  
  1822.         delay
  1823.         move.b  D6,nic_tbcr0(A4)           ; set tx byte count lo
  1824.         ror.w   #8,D6
  1825.         delay
  1826.         move.b  D6,nic_tbcr1(A4)           ; set tx byte count hi
  1827.         delay
  1828.         move.b  #DSCM_NODMA|DSCM_TRANS|DSCM_START,nic_cr(A4) ; start tx
  1829.         move.l  execbase(PC),A6
  1830.         jsr     _LVOEnable(A6)             ; enable interrupts
  1831. .ti.termio:
  1832.         move.l  A3,A1
  1833.         bsr     TermIO                     ; finish IOrequest
  1834.         bra     .ti.next                   ; process next ioreq
  1835. .ti.done:
  1836.  
  1837.         move.l  dd_mapping_tx(a5),a1
  1838.         move.l  dd_pcires(a5),a6
  1839.         jsr     PCIRRestorePCIPage(a6)
  1840.  
  1841.         IFGT    Printer
  1842.  
  1843.         bsr     DPutHexL
  1844.         bsr     DPutMsg
  1845.         dc.l    Rel4Msg
  1846.  
  1847.         ENDC
  1848.         
  1849.         movem.l (A7)+,D4-D7/A2-A6
  1850.         moveq   #0,d0
  1851.         rts
  1852.  
  1853. Rel4Msg         STRINGR " PCI erros - tx interrupt"
  1854. RXIntMsg        STRINGR "service rx interrupt"
  1855.  
  1856. ;============================================================
  1857. ;                   rxintcode(device)
  1858. ;                               a1
  1859. ;============================================================
  1860. ;
  1861. ;                service rx interrupts
  1862. ;
  1863. ; do PCI access - interrupt function
  1864. rxintcode:
  1865.         movem.l D6/D7/A3-A6,-(A7)
  1866.         move.l  A1,A5                             ; a5 = device
  1867.                                                   ; a4 = IOBase
  1868.  
  1869.         IFGT    Printer
  1870.  
  1871.         bsr     DPutMsg
  1872.         dc.l    RXIntMsg
  1873.         
  1874.         ENDC
  1875.  
  1876.         move.l  dd_mapping_rx(a5),a1
  1877.         move.l  dd_pcires(a5),a6
  1878.         jsr     PCIRStorePCIPage(a6)
  1879.         
  1880.         move.l  map_address(a1),a4                ; a4 = nic registers
  1881.  
  1882.         move.l  execbase(PC),A6
  1883. .ri.nextpage:
  1884.         jsr     _LVODisable(A6)
  1885.         delay
  1886.         move.b  #DSCM_NODMA|DSCM_PG1|DSCM_START,nic_cr(A4) ; select bank 1
  1887.         moveq   #0,D7
  1888.         move.b  nic_curr(A4),D7                   ; d7 = current page
  1889.         delay
  1890.         move.b  #DSCM_NODMA|DSCM_START,nic_cr(A4) ; select bank 0
  1891.         jsr     _LVOEnable(A6)
  1892.         moveq   #0,D6
  1893.         delay
  1894.         move.b  nic_bnry(A4),D6
  1895.         addq.w  #1,D6                             ; d6 = next page (boundary+1)
  1896.         cmp.w   #RBUFEND/256,D6
  1897.         blo.s   .ri.nowrap                           ; end of buffer mem  ?
  1898.         moveq   #RBUF/256,D6                      ; wrap around to start
  1899. .ri.nowrap:
  1900.         cmp.w   D6,D7                             ; current page = next page ?
  1901.         beq     .ri.done                             ; if so then nothing to get
  1902.         move.w  D6,D0
  1903.         asl.w   #8,D0                             ; d0 = 16 bit page address
  1904.         lea     rx_header(pc),A1                  ; a1 = buffer
  1905.         moveq   #20,D1                            ; 20 bytes to get
  1906.         bsr     RemoteRead                        ; get packet header
  1907.         move.b  rx_header+prhdr_status(pc),d0
  1908.         and.b   #DSRS_RPC,d0                      ; complete packet received ?
  1909.         bne.s   .ri.goodpacket
  1910.         addq.l  #1,dd_errors(a5)                  ; another packet error
  1911.         bra.s   .ri.next
  1912. .ri.goodpacket:
  1913.         move.w  D6,D0
  1914.         lea     rx_header(pc),A1
  1915.         bsr     readpacket                        ; read whole packet into ioreqs
  1916. .ri.next:
  1917.         moveq   #0,D0
  1918.         move.b  rx_header+prhdr_nxtpg(pc),D0      ; get next page number
  1919.         move.w  D0,D7
  1920.         subq.w  #1,D0                             ; nxtpage-1 = new boundary
  1921.         cmp.w   #RBUF/256,D0
  1922.         bge.s   .ri.boundary                         ; wrap if before 1st page
  1923.         moveq   #(RBUFEND/256)-1,D0
  1924. .ri.boundary:
  1925.         delay
  1926.         move.b  D0,nic_bnry(A4)                   ; set new boundary
  1927.         bra     .ri.nextpage                         ; back for more
  1928. .ri.done:
  1929.         delay
  1930.         move.b  #DSCM_NODMA|DSCM_START,nic_cr(A4) ; select bank 0
  1931.         jsr     _LVODisable(A6)
  1932.         delay
  1933.         move.b  nic_rsr(a4),d0                    ; read rx status
  1934.         delay
  1935.         move.b  nic_cntr0(A4),D0
  1936.         delay
  1937.         move.b  nic_cntr1(A4),D0                  ; read counters
  1938.         delay
  1939.         move.b  nic_cntr2(A4),D0
  1940.         or.b    #DSIM_OVWE|DSIM_RXEE|DSIM_PRXE,dd_imr(A5)
  1941.         move.b  dd_imr(a5),nic_imr(a4)            ; allow rx interrupts
  1942.         jsr     _LVOEnable(A6)
  1943.  
  1944.         move.l  dd_mapping_rx(a5),a1
  1945.         move.l  dd_pcires(a5),a6
  1946.         jsr     PCIRRestorePCIPage(a6)
  1947.  
  1948.         IFGT    Printer
  1949.  
  1950.         bsr     DPutHexL
  1951.         bsr     DPutMsg
  1952.         dc.l    Rel5Msg
  1953.         
  1954.         ENDC
  1955.  
  1956.         movem.l (A7)+,D6/D7/A3-A6
  1957.         moveq   #0,D0
  1958.         rts
  1959.  
  1960. Rel5Msg         STRINGR " PCI errors - rx interrupt"
  1961.  
  1962.  
  1963. ;==============================================================
  1964. ;             readpacket( device, pkthdr, page,  IOBase)
  1965. ;                           a5     a1     d0.w    A4
  1966. ;==============================================================
  1967. ;
  1968. ; get packet from network card and feed it to next ioreq
  1969. ;
  1970. ; Inputs:
  1971. ;
  1972. ;       pkthdr = packet header info extracted from nic
  1973. ;
  1974. ;       page = 256 byte page in nic RAM that holds packet
  1975. ;
  1976. ;
  1977. ; call Remote Read - called from interrupt
  1978. ; ZAMIANIC A4 NA A2
  1979.  
  1980. ReadPackMsg     STRINGR "Read packet function"
  1981.  
  1982. readpacket:
  1983.         movem.l D3-D7/A2-A6,-(A7)
  1984.         move.l  D0,D7                          ; D7 = page
  1985.         move.l  A1,A2                          ; a2 = header
  1986.         moveq   #0,D6
  1987.  
  1988.         IFGT    Printer
  1989.  
  1990.         bsr     DPutMsg
  1991.         dc.l    ReadPackMsg
  1992.  
  1993.         ENDC
  1994.         
  1995.         move.b  prhdr_sz1(A2),D6
  1996.         lsl.w   #8,D6                          ; D6 = packet data length
  1997.         move.b  prhdr_sz0(A2),D6
  1998.         sub.w   #prhdr_sizeof+ether_data,D6    ; D6 = length of user data
  1999.         moveq   #0,D3
  2000.         move.w  prhdr_sizeof+ether_type(A2),D3 ; d3 = type
  2001.         move.l  dd_readlist(A5),A3             ; a3 = first ioreq
  2002.         bra.s   .rp.getreq                        ; find a suitable ioreq
  2003. .rp.checkreq:
  2004.         cmp.l   ios2_packettype(A3),D3         ; does it want our packet ?
  2005.         beq.s   .rp.gotreq
  2006.         cmp.w   #1500,d3
  2007.         bhi.s   .rp.nextreq                       ; accept 802.3 packets
  2008.         cmp.l   #1500,ios2_packettype(A3)
  2009.         bls.s   .rp.gotreq
  2010. .rp.nextreq:
  2011.         move.l  D1,A3                          ; a3 = next ioreq in list
  2012. .rp.getreq:
  2013.         move.l  (A3),D1                        ; end of list ?
  2014.         bne.s   .rp.checkreq
  2015.         bra     .rp.done
  2016. .rp.gotreq:
  2017.         move.l  A3,A1
  2018.         move.l  execbase(PC),A6
  2019.         jsr     _LVORemove(A6)                 ; remove ioreq from list
  2020.         lea     ios2_dstaddr(A3),A0
  2021.         moveq   #ETHER_ADDR_SIZE-1,D0
  2022. .rp.dst:
  2023.         move.b  (A2)+,(A0)+                    ; extract the dest address
  2024.         dbf     D0,.rp.dst
  2025.         cmp.w   #$ffff,ios2_dstaddr(a3)
  2026.         bne.s   .rp.getsrc                        ; address = Broadcast ?
  2027.         cmp.l   #$ffffffff,ios2_dstaddr+2(a3)
  2028.         bne.s   .rp.getsrc
  2029.         bset    #SANA2IOB_BCAST,IO_FLAGS(a3)   ; set BROADCAST flag in ioreq
  2030. .rp.getsrc:
  2031.         lea     ios2_srcaddr(A3),A0
  2032.         moveq   #ETHER_ADDR_SIZE-1,D0
  2033. .rp.src:
  2034.         move.b  (A2)+,(A0)+                    ; extract the src address
  2035.         dbf     D0,.rp.src
  2036.         move.w  D7,D5
  2037.         asl.w   #8,D5                          ; address=page*256
  2038.         add.w   #prhdr_sizeof+ether_data,D5    ; skip pageheader and etherheader
  2039.         btst    #SANA2IOB_RAW,IO_FLAGS(A3)
  2040.         beq.s   .rp.getpacket                     ; is etherheader wanted ?
  2041.         moveq   #ether_data,D0
  2042.         add.l   D0,D6                        ; add header length for raw packet
  2043.         sub.w   D0,D5                        ; backup nic address to include header
  2044. .rp.getpacket:
  2045.         lea     rxbuffer,A1
  2046.         move.w  D5,D0
  2047.         move.w  D6,D1
  2048.         bsr     RemoteRead                   ; get packet from network card's RAM
  2049.         move.l  dd_copytobuf(a5),a2
  2050.         move.l  ios2_data(A3),A0
  2051.         lea     rxbuffer,A1
  2052.         move.l  D6,ios2_datalength(A3)       ; set data length in ioreq
  2053.         move.l  d6,d0
  2054.         jsr     (a2)                         ; call copytobuf
  2055.         move.l  A3,A1
  2056.         bsr     TermIO                       ; IO finished
  2057. .rp.done:
  2058.         movem.l (A7)+,D3-D7/A2-A6
  2059.         rts
  2060.  
  2061. ;======================================================================
  2062. ;                  init_card(device)
  2063. ;                              a1
  2064. ;======================================================================
  2065. ;
  2066. ;                    Initialise PCMCIA card
  2067. ;
  2068. ; we use PCI card instead of PCMCIA one
  2069. ; no PCI access
  2070.  
  2071. InitCardMsg     STRINGR "Init card"
  2072.  
  2073. init_card:
  2074.         movem.l D2-D6/A3/A6,-(A7)
  2075.         move.l  A1,A3                        ; a3 = device
  2076.         
  2077.         IFGT    Printer
  2078.  
  2079.         bsr     DPutMsg
  2080.         dc.l    InitCardMsg
  2081.  
  2082.         ENDC
  2083.  
  2084.         lea     dd_netinterrupt(a3),a1       ; init interrupts
  2085.         lea     DeviceName(pc),a0
  2086.         move.l  a0,LN_NAME(a1)
  2087.         move.b  #20,LN_PRI(a1)               ; high priority for I/O card
  2088.         move.l  a3,IS_DATA(a1)
  2089.         move.l  #status_int_code,IS_CODE(a1)
  2090.         move.l  dd_pciconfig(a3),a0
  2091.         move.b  pcie_Cfg+pci_InterruptLine(a0),d0 
  2092.         move.l  execbase(pc),a6
  2093.         jsr     _LVOAddIntServer(a6)
  2094.         
  2095. .ic.ok:
  2096.         moveq   #0,D0                        ; card is active, return OK
  2097. .ic.done:
  2098.         movem.l (A7)+,D2-D6/A3/A6
  2099.         rts
  2100.  
  2101.  
  2102.  
  2103.  
  2104. ;=================================================================
  2105. ;              initialise device data structures
  2106. ;=================================================================
  2107. ;
  2108. ;   init_device(device)
  2109. ;                 a1
  2110. ;
  2111. ; there is no need to have PCIpage - no PCI access
  2112. InitDevMsg      STRINGR "init_device"
  2113.  
  2114. init_device:
  2115.         move.l  A3,-(A7)
  2116.         move.l  A1,A3
  2117.  
  2118.         IFGT    Printer
  2119.  
  2120.         bsr     DPutMsg
  2121.         dc.l    InitDevMsg
  2122.  
  2123.         ENDC
  2124.  
  2125.         bset    #DDB_DEVINIT,dd_flags(A3)     ; already initialised ?
  2126.         bne     .id.done
  2127.         lea     dd_readlist(A3),A0
  2128.         move.l  A0,MLH_TAILPRED(A0)
  2129.         lea     MLH_TAIL(A0),A1               ; New MinList for read queue
  2130.         clr.l   (A1)
  2131.         move.l  A1,(A0)
  2132.         lea     dd_writelist(A3),A0
  2133.         move.l  A0,MLH_TAILPRED(A0)           ; New MinList for write queue
  2134.         lea     MLH_TAIL(A0),A1
  2135.         clr.l   (A1)
  2136.         move.l  A1,(A0)
  2137.         lea     dd_eventlist(A3),A0           ; New MinList for event queue
  2138.         move.l  A0,MLH_TAILPRED(A0)
  2139.         lea     MLH_TAIL(A0),A1
  2140.  
  2141.         clr.l   (A1)
  2142.         move.l  A1,(A0)
  2143.         move.b  #NT_INTERRUPT,dd_rxint+LN_TYPE(a3)
  2144.         move.b  #16,dd_rxint+LN_PRI(a3)
  2145.         lea     rxintname(pc),a0
  2146.         move.l  a0,dd_rxint+LN_NAME(a3)       ; set up rx swi
  2147.         lea     rxintcode(pc),a0
  2148.         move.l  a0,dd_rxint+IS_CODE(a3)
  2149.         move.l  a3,dd_rxint+IS_DATA(a3)
  2150.         move.b  #NT_INTERRUPT,dd_txint+LN_TYPE(a3)
  2151.         move.b  #0,dd_txint+LN_PRI(a3)
  2152.         lea     txintname(pc),a0
  2153.         move.l  a0,dd_txint+LN_NAME(a3)       ; set up tx swi
  2154.         lea     txintcode(pc),a0
  2155.         move.l  a0,dd_txint+IS_CODE(a3)
  2156.         move.l  a3,dd_txint+IS_DATA(a3)
  2157. .id.done:
  2158.         move.l  (A7)+,A3
  2159.         rts
  2160.  
  2161.  
  2162. ; INT from PCI card
  2163. ;
  2164. ;   Occurs whenever a PCMCIA status line changes
  2165. ;
  2166. ;   eg. when the network card activates it's interrupt line
  2167. ;
  2168. ;
  2169. ;  entry:   a1 = device
  2170. ;
  2171. ;  exit:    d0 must be preserved!
  2172. ;
  2173. ; do PCI access - interrupt function
  2174.  
  2175. IntMsg  STRINGR  " => PCI Interrupt"
  2176.  
  2177. status_int_code:
  2178.         movem.l D2-D6/A0-A6,-(A7)
  2179.         move.l  A1,A4                      ; a4 = device
  2180.  
  2181.         btst    #DDB_ONLINE,dd_flags(a4)   ; is device online ?
  2182.         beq     .si.done
  2183.  
  2184. ; StorePCIPage - interrupt server
  2185.         move.l  dd_mapping_int(a4),a1
  2186.         move.l  dd_pcires(a4),a6
  2187.         jsr     PCIRStorePCIPage(a6)
  2188.         move.l  map_address(a1),a3              ; a3 = nic I/O address
  2189.  
  2190.         delay
  2191.         move.b  nic_cr(a3),d5              ; save old command
  2192.         delay
  2193.         move.b  #0,nic_imr(a3)             ; prevent nic interrupts
  2194.         bra     .si.checkint
  2195.  
  2196. ; interrupt service loop    (D3 = interrupt status) 
  2197.  
  2198. .si.intloop:
  2199.         ; d3 - status wypisac
  2200.  
  2201.         IFGT    Printer
  2202.  
  2203.         clr.l   d0
  2204.         move.b  d3,d0
  2205.         bsr     DPutHexB
  2206.         bsr     DPutMsg
  2207.         dc.l    IntMsg
  2208.  
  2209.         ENDC
  2210.  
  2211.         btst    #DSIB_ROVRN,d3
  2212.         beq     .si.no_overflow
  2213.  
  2214. ; receiver ring buffer overflowed (eek!)
  2215.         addq.l  #1,dd_overflows(a4)
  2216.         delay
  2217.         move.b  #0,nic_rbcr0(a3)
  2218.         delay
  2219.         move.b  #0,nic_rbcr1(a3)                  ; reset remote byte count
  2220.         delay
  2221.         move.b  #DSTC_LB0,nic_tcr(a3)
  2222.         delay                                     ; monitor mode
  2223.         move.b  #DSRC_MON,nic_rcr(a3)
  2224.         delay
  2225.         move.b  #DSCM_NODMA|DSCM_START,nic_cr(a3) ; try to restart controller
  2226.         delay
  2227.         move.b  #DSRC_AB,nic_rcr(a3)
  2228.         delay                                     ; normal rx mode
  2229.         move.b  #0,nic_tcr(a3)
  2230.  
  2231. .si.no_overflow:
  2232.         btst    #DSIB_RXE,d3
  2233.         beq.s   .si.norxerr
  2234.         addq.l  #1,dd_errors(a4)
  2235.         delay
  2236.         move.b  nic_rsr(a3),d0           ; read rx status
  2237.         delay
  2238.         move.b  nic_cntr0(A3),D0
  2239.         delay
  2240.         move.b  nic_cntr1(A3),D0         ; read counters
  2241.         delay
  2242.         move.b  nic_cntr2(A3),D0
  2243.         bra.s   .si.rx
  2244.  
  2245. .si.norxerr:
  2246.         btst    #DSIB_RX,d3
  2247.         beq.s   .si.no_rx
  2248.  
  2249. ; new packet(s) arrived in receive ring buffer
  2250. .si.rx:
  2251.         and.b   #~(DSIM_OVWE|DSIM_RXEE|DSIM_PRXE),dd_imr(A4) ; ignore rx ints
  2252.         lea     dd_rxint(A4),A1
  2253.         move.l  execbase(PC),A6
  2254.         jsr     _LVOCause(A6)            ; to copy packet(s) into waiting ioreqs
  2255.  
  2256. .si.no_rx:
  2257.         btst    #DSIB_TXE,d3
  2258.         bne.s   .si.tx
  2259.         btst    #DSIB_TX,d3
  2260.         beq     .si.no_tx
  2261.  
  2262. ; a packet has just been transmitted
  2263. .si.tx:
  2264.         moveq   #0,d0
  2265.         delay
  2266.         move.b  nic_ncr(A3),d0           ; read collision count
  2267.         add.l   d0,dd_collisions(a4)
  2268.         bclr    #DDB_TX,dd_flags(A4)     ; buffer now free
  2269.         lea     dd_txint(A4),A1
  2270.         move.l  execbase(PC),A6
  2271.         jsr     _LVOCause(A6)            ; to transmit next packet
  2272.  
  2273. .si.no_tx:
  2274.         btst    #DSIB_CTRS,d3            ; counter overflow ?
  2275.         bne.s   .si.counter
  2276.         bra.s   .si.checkint                ; all ints processed
  2277.  
  2278. ; counter overflow
  2279. .si.counter:
  2280.         delay
  2281.         move.b  nic_cntr0(A3),D0
  2282.         delay
  2283.         move.b  nic_cntr1(A3),D0         ; read counters
  2284.         delay
  2285.         move.b  nic_cntr2(A3),D0
  2286.  
  2287. .si.checkint:
  2288.         delay
  2289.         move.b  nic_isr(a3),D3           ; D3 = nic interrupt status
  2290.         delay
  2291.         move.b  d3,nic_isr(a3)           ; clear current interrupt bit(s)
  2292.         and.b   dd_imr(a4),d3
  2293.         bne     .si.intloop                 ; any valid interrupts ?
  2294. .si.end:
  2295.         delay
  2296.         move.b  d5,nic_cr(a3)            ; restore old command
  2297.  
  2298.         move.b  dd_imr(a4),nic_imr(a3)   ; enable nic interrupts
  2299. ; restore pci
  2300.         move.l  dd_mapping_int(a4),a1
  2301.         move.l  dd_pcires(a4),a6
  2302.         jsr     PCIRRestorePCIPage(a6)
  2303.         
  2304. .si.done:
  2305.         clr.l   d0
  2306.         movem.l (A7)+,D2-D6/A0-A6
  2307.         rts
  2308.  
  2309. rxintname:
  2310.         dc.b "pcinet rx softint",0
  2311. txintname:
  2312.         dc.b "pcinet tx softint",0
  2313.  
  2314. pcirname:
  2315.         dc.b "micronik_pci.resource",0
  2316.  
  2317. pciename:
  2318.         dc.b "pciexpansion.library",0
  2319. pciever:        EQU    0
  2320.  
  2321.  
  2322. NET_TAGS:       dc.l  PCIE_BASECLASSCODE,2    ; network controller
  2323.                 dc.l  0,0  
  2324.  
  2325. dosname:
  2326.         dc.b "dos.library",0
  2327.  
  2328. configname:
  2329.         dc.b "S:cnetdev.config",0
  2330.  
  2331. DeviceName:
  2332.         dc.b    "pcinet.device",0
  2333. IDString:
  2334.         dc.b    "$VER: pcinet.device "
  2335.         dc.b    VERSION+48,".",REVISION+48," "
  2336.         dc.b    "02.04.1998"
  2337.         dc.b    " by Krzysztof Rudnik (rudnik@ias.wat.waw.pl)",10,0
  2338.  
  2339.         CNOP    0,4
  2340.  
  2341. ; devicequery block
  2342.  
  2343. size_supplied:
  2344.         dc.l    S2DQ_SIZE            ; bytes supplied (size of this block)
  2345.         dc.l    0                    ; this is type 0
  2346.         dc.l    0                    ; this document is level 0
  2347.         dc.w    ETHER_ADDR_SIZE*8    ; address size in bits
  2348.         dc.l    ETHERPKT_SIZE        ; maximum packet data size
  2349.         dc.l    10000000             ; line rate (10 Megabits/sec)
  2350.         dc.l    S2WIRETYPE_ETHERNET  ; what the wire is
  2351.  
  2352.  
  2353. ; default station address to use if the card won't give it to us.
  2354.  
  2355. default_address:
  2356.         dc.b    $00,$00,$12,$34,$56,$78 ; replace this with your card's address!
  2357.  
  2358.  
  2359. ;--------------------------------------------------------
  2360. ;                      Global data
  2361. ;--------------------------------------------------------
  2362.  
  2363. execbase    dc.l 0      ; local copy of execbase
  2364.  
  2365. rx_header:
  2366.             ds.b    20             ; received packet header
  2367.  
  2368.  
  2369. DPutMsg:        ; jak DPutStr tylko parametr jest dc.l po wywolaniu
  2370.                 movem.l d0/a0,-(sp)
  2371.                 ; poprawic adres powrotu
  2372.                 addq.l  #4,8(sp)
  2373.                 ; parametr w kodzie po instrukcji wywolania
  2374.                 move.l  8(sp),a0
  2375.                 move.l  -4(a0),a0
  2376.                 ; w A0 adres stringu
  2377.                 bra     DPutStr1
  2378.  
  2379. DPutStrtt:      movem.l d0/a0,-(sp)
  2380. DPutStr1:       move.b  (a0)+,d0
  2381.                 bne     .Dputchar
  2382.                 movem.l (sp)+,d0/a0
  2383.                 rts
  2384. .Dputchar:      bsr     PRawPutChar
  2385.                 bra     DPutStr1
  2386.  
  2387. ; wypisac long d0 w HEXie jako %8X
  2388. DPutHexL:       swap    d0
  2389.                 bsr     DPutHexW
  2390.                 swap    d0
  2391. ; wypisac word d0 w HEXie jako %4X
  2392. DPutHexW:       ror.w   #8,d0
  2393.                 bsr     DPutHexB
  2394.                 rol.w   #8,d0
  2395. ; wypisac byte d0 w HEXie jako %2X
  2396. DPutHexB:       ror.b   #4,d0
  2397.                 bsr     DPutHexD
  2398.                 rol.b   #4,d0
  2399. ; wypisanie najmlodszych 4 bitow d0 w hex
  2400. DPutHexD:       movem.l d0/a0,-(sp)
  2401.                 and.l   #$F,d0
  2402.                 move.b  HexDigits(pc,d0.w),d0
  2403.                 bsr     PRawPutChar
  2404.                 movem.l (sp)+,d0/a0
  2405.                 rts
  2406.  
  2407. HexDigits:      dc.b    "0123456789ABCDEF"
  2408.  
  2409. ; to bylo w debug.lib - ale ja chce to miec razem, zeby nie kombinowac 
  2410. ; z linkowaniem
  2411. DPutChar:
  2412. PRawPutChar:     tst.b   $BFD000
  2413.                  tst.b   $BFD000
  2414. l30$166:         btst    #1,$BFD000
  2415.                  bne     l30$555
  2416.                  btst    #2,$BFD000
  2417.                  beq     l30$555
  2418.                  btst    #0,$BFD000
  2419.                  bne.s   l30$166
  2420.                  move.b  #$FF,$BFE301
  2421.                  move.b  d0,$BFE101
  2422.                  tst.b   $BFD000
  2423.                  tst.b   $BFD000
  2424. l30$555:         rts
  2425.  
  2426.  
  2427. ; Additional function called from RemoteRead & RemoteWrite
  2428. ; the same parameters - HEX dumps memory address A1, len D1
  2429. ; do not modify any registers. Limits count to 128 bytes
  2430. ;=================================================================
  2431. ;         DumpMem( buffer, count)
  2432. ;                   a1     d1.w  
  2433. ;=================================================================
  2434. ;
  2435. DPutMem:        movem.l d0-d4/a1,-(sp)
  2436.                 cmp.w   #256,d1
  2437.                 blt     lenok
  2438.                 move.w  #256,d1
  2439. lenok:
  2440.                 move.l  #0,d3                   ; BYTE address
  2441. LineLoop:       move.l  #15,d4
  2442.                 move.l  d3,d0
  2443.                 bsr     DPutHexW
  2444.                 bsr     DPutMsg
  2445.                 dc.l    LineHeaderMsg
  2446.  
  2447. ByteLoop:       clr.l   d0
  2448.                 move.b  (a1)+,d0
  2449.                 add.l   #1,d3
  2450.                 bsr     DPutHexB
  2451.                 move.b  #' ',d0
  2452.                 bsr     DPutChar
  2453.                 sub.w   #1,d1
  2454.                 dbeq    d4,ByteLoop
  2455. LineTrailer:
  2456.                 bsr     DPutMsg
  2457.                 dc.l    EOLMsg
  2458.                 
  2459.                 tst.w   d1
  2460.                 bne     LineLoop
  2461.                 bsr     DPutMsg
  2462.                 dc.l    DumpTrailerMsg
  2463.                 movem.l (sp)+,d0-d4/a1
  2464.                 rts
  2465.                 
  2466. LineHeaderMsg   STRING  " : "
  2467. DumpTrailerMsg  STRINGR "==================="
  2468.  
  2469. Endcode:
  2470.  
  2471.  section buffers,bss
  2472.  
  2473. rxbuffer:
  2474.         ds.b  1600             ; received packet buffer
  2475.  
  2476. txbuffer:
  2477.         ds.b  1600             ; transmit packet buffer
  2478.  
  2479.         END
  2480.